Ios iPhone模拟器中的图像和真实设备上的图像不一样

Ios iPhone模拟器中的图像和真实设备上的图像不一样,ios,xcode,ios-simulator,Ios,Xcode,Ios Simulator,背景 我需要得到一个正方形的图像,以填补一个表单元格边到边,有一个小的空白,并有它的工作在所有设备 我处理不同设备的方法是基于设备以编程方式设置表中的行高,并使用AspectFit使图像填充行——当我知道要将行高设置为什么值时,这种方法很有效。只需几次猜测就可以搞定 问题 图像在模拟器中的显示方式与在真实设备上的显示方式不同,这使得在模拟器上无法进行测试,并要求真实设备具有确定性 这是图像和模拟器的已知问题吗?我是否缺少一些变通方法或设置 我想让模拟器演示与设备演示与图像相匹配,这样我就可以在不

背景

我需要得到一个正方形的图像,以填补一个表单元格边到边,有一个小的空白,并有它的工作在所有设备

我处理不同设备的方法是基于设备以编程方式设置表中的行高,并使用AspectFit使图像填充行——当我知道要将行高设置为什么值时,这种方法很有效。只需几次猜测就可以搞定

问题

图像在模拟器中的显示方式与在真实设备上的显示方式不同,这使得在模拟器上无法进行测试,并要求真实设备具有确定性

这是图像和模拟器的已知问题吗?我是否缺少一些变通方法或设置

我想让模拟器演示与设备演示与图像相匹配,这样我就可以在不访问大量物理设备的情况下进行有效测试

提前谢谢

参考图像

第一张图片来自iPhone6模拟器。第二个(正确的一个)来自真实的iPhone6设备。您不会从模拟器中猜到实际设备上的图像是正确的

我们在其他模拟器上也看到了这个问题,比如iPhone7模拟器和iPhoneSE模拟器,所以我们假设这是所有模拟器的问题

此控制器的源代码

import UIKit
import AVFoundation
import GRDB
import SwiftPhotoGallery

class SpeciesDescriptionController: UITableViewController, SwiftPhotoGalleryDataSource, SwiftPhotoGalleryDelegate {

    let tableCell = "TableCell"
    var target_id : Int64 = 0
    var item_scanned : Bool = false
    let scanned = Scanned()

    var species_array = [Species]()
    var species : Species!

    var primary_image : Image!
    var image_names = [String]()

    let favorites = Favorites()


    @IBAction func toggle_favorites(_ sender: Any) {
        if (favorites.check(species_id: species.id!) == true) {
            favorites.remove(species_id: species.id!)
        } else {
            favorites.add(content_id: species.id!, table_name: "Species", display_name: species.display_name)
        }
        set_favorites_status()
    }


    @IBOutlet weak var favorites_status: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        loadSpeciesDescription()
        loadPrimaryImage()
        setTitle()
        formatTable()
        set_favorites_status()
        if item_scanned == true {
            scanned.add(content_id: species.id!, table_name: "Species", display_name: species.display_name)
        }

        let modelName = UIDevice.current.modelName
        print("\n\nThe model name is: \(modelName)\n\n")
    }


    private func set_favorites_status() {
        if (favorites.check(species_id: species.id!) == true) {
            favorites_status.image = UIImage(named: "glyphicons-50-star")
        } else {
            favorites_status.image = UIImage(named: "glyphicons-49-star-empty")
        }
    }


    private func loadSpeciesDescription() {
        species = try! dbQueue.inDatabase { db in
            try Species.fetchOne(db, key: target_id)
        }
    }

    private func loadPrimaryImage() {
        let visibleIdColumn = Column("visible_id")
        let visibleTypeColumn = Column("visible_type")
        let primaryPhotoColumn = Column("primary_photo")
        let request = Image.filter(visibleIdColumn == species.id )
            .filter(visibleTypeColumn == "Species")
            .filter(primaryPhotoColumn == "t")
        primary_image = try! dbQueue.inDatabase { db in
            try request.fetchOne(db)
        }
    }


    func formatTable() {
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.tableFooterView = UIView(frame: CGRect.zero) // deny empty table rows
    }


    func setTitle() {
        self.title =  species.display_name
    }


    func species_names() -> String {
        var all_names: String = ""
        let scientific_names = "Scientific: \(species.scientific_name)\n"
        let common_names = "Common: \(species.common_name)"
        let other_names = "\nNoongar: \(species.other_names)"

        all_names = scientific_names + common_names
        if (other_names != "\nNoongar: ") {
            all_names = all_names + other_names
        }
        return all_names
    }

    /////////////////// Table //////////////////////////////

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 6
    }


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }


    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        var title : String = ""
        switch section {
        case 0 : title = " " // must have blank to print the blank section header
        case 1 : title = "Names"
        case 2 : title = "Audio"
        case 3 : title = "Identification"
        case 4 : title = "Description"
        case 5 : title = "Range"
        default: title = "Not defined..."
        }
        return title
    }


    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    {
        if indexPath.section == 0 {
            return CGFloat(row_height_for_device())
        } else {
            return  UITableViewAutomaticDimension
        }
    }

    func row_height_for_device() -> Int {
        switch UIDevice.current.modelName {
        case "iPhone SE" :
            return 290  //confirmed to work with SE
        case "iPhone 6", "iPhone 6s"   :
            return 290  // confirmed to work with 6
        case "iPhone 7" :
            return 348  //
        case "iPhone 8"   :
            return 348  //
        case "iPhone 6 Plus", "iPhone 6s Plus","iPhone 7 Plus", "iPhone 8 Plus"   :
            return 380
        case "iPhone X" :
            return 400
        default:
            // handles 2G, 3G, 3GS, 4, 4s, 5, 5s, 5c, SE
            // confirmed to work with SE
            return 290
        }
    }



    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: tableCell) as UITableViewCell?
        if (cell == nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: tableCell)
        }

        cell!.imageView?.image = nil
        cell!.imageView?.contentMode = .scaleAspectFit
        cell!.textLabel?.text = nil
        cell!.textLabel?.numberOfLines = 0
        cell!.textLabel?.lineBreakMode = .byWordWrapping
        cell!.textLabel?.font = UIFont.systemFont(ofSize: 16)

        switch indexPath.section {
        case 0 :
            let image_file_name = "primary_\(primary_image.image_file_name)"
            print("The image the app is looking for is called: \(image_file_name)")
            cell!.imageView?.image =  UIImage(named: image_file_name)
        case 1 : cell!.textLabel?.text = species_names()
        case 2 :
            cell!.imageView?.image = UIImage(named: "glyphicons-169-ear-plugs")
            cell!.textLabel?.text = "1 Minute Audio Summary"
        case 3 : cell!.textLabel?.text = species.identification
        case 4 : cell!.textLabel?.text = species.description
        case 5 : cell!.textLabel?.text = species.range
        default :  cell!.textLabel?.text = ""

        }
        return cell!
    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 2 {
            textToSpeech(audio_summary: species.audio_summary)
        }
        if indexPath.section == 0 {
            show_gallery(species_id: species.id!)
        }

    }

    func standard_alert(_ alertTitle: String, alertMessage: String) -> Void {
        let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Ok"), style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }


    func bail_out() {
        performSegue(withIdentifier: "no_content", sender: nil)
    }

    func textToSpeech(audio_summary : String)
    {
        let synth = AVSpeechSynthesizer()
        var myUtterance = AVSpeechUtterance(string: "")
        myUtterance = AVSpeechUtterance(string: audio_summary)
        myUtterance.voice = AVSpeechSynthesisVoice(language: "en-AU")
        synth.speak(myUtterance)
    }


    ///////////

    func show_gallery(species_id: Int64) {
        // load_image_names(species_id: species_id)
        let image_file_name = "large_primary_" + primary_image.image_file_name
        image_names = [image_file_name]  // array of one item for now
        let gallery = SwiftPhotoGallery(delegate: self, dataSource: self)
        gallery.backgroundColor = UIColor.black
        gallery.pageIndicatorTintColor = UIColor.gray.withAlphaComponent(0.5)
        gallery.currentPageIndicatorTintColor = UIColor.white
        gallery.hidePageControl = true
        present(gallery, animated: true, completion: nil)
    }


    // MARK: SwiftPhotoGalleryDataSource Methods

    func numberOfImagesInGallery(gallery: SwiftPhotoGallery) -> Int {
        return image_names.count
    }

    func imageInGallery(gallery: SwiftPhotoGallery, forIndex: Int) -> UIImage? {
        return UIImage(named: image_names[forIndex])
    }

    // MARK: SwiftPhotoGalleryDelegate Methods

    func galleryDidTapToClose(gallery: SwiftPhotoGallery) {
        dismiss(animated: true, completion: nil)
    }


} // class

根据评论讨论,最初的问题是由于设备显示选项设置为缩放。一旦关闭缩放,模拟器将再次与设备匹配

另一方面。。。我假设目标是让图像在单元格中居中,每边有一点填充(20分左右),同时保持正方形?如果是的话

我建议创建一个自定义单元格类

添加一个约束为顶部:0、底部:0、前导20、尾随:20的
UIImageView
。然后将图像视图设置为具有
1:1
比率约束


现在,图像视图将“自动”拉伸到单元格的宽度(减去填充),自动布局将设置高度以匹配宽度。无需手动计算/设置行高。

这与“模拟器和设备”之间的差异无关。问题是您使用的模拟器与设备不同。你所有的图像大小是相同的,还是不同的?模拟器与iPhone 6模拟器的设备相匹配。iphone6设备。我仔细检查了一下。图像被裁剪成相同的大小和形状(正方形和480x480)。。。当时发生了一些奇怪的事情。正如您所注意到的,忽略图像,即使标签中的文本也会有不同的布局——“Common:…”行在设备图像上,而不是在模拟器图像上。您是否有一些正在进行调整的代码?或者这都是通过自动布局和约束完成的?我为控制器添加了完整的源代码。注意:我简要地注释了设备模型逻辑,并返回了290。问题还在继续——它在iPhone 6的实际设备上看起来是正确的,但在模拟器中却没有。(我这样做是为了确保模拟器获得与设备相同的值。然后我将源代码返回到您现在看到的版本。我认为您可能试图解决错误的问题……但是,首先,您可以发布不同的模拟器屏幕截图吗?您的模拟器图像是
606x1079
,设备图像是
640x1136
…在运行模拟器时,您应该能够选择
窗口->像素精度
,然后您可以将屏幕截图保存在相同的尺寸上…这样比较两者就更容易了。