Ios iPhone模拟器中的图像和真实设备上的图像不一样
背景 我需要得到一个正方形的图像,以填补一个表单元格边到边,有一个小的空白,并有它的工作在所有设备 我处理不同设备的方法是基于设备以编程方式设置表中的行高,并使用AspectFit使图像填充行——当我知道要将行高设置为什么值时,这种方法很有效。只需几次猜测就可以搞定 问题 图像在模拟器中的显示方式与在真实设备上的显示方式不同,这使得在模拟器上无法进行测试,并要求真实设备具有确定性 这是图像和模拟器的已知问题吗?我是否缺少一些变通方法或设置 我想让模拟器演示与设备演示与图像相匹配,这样我就可以在不访问大量物理设备的情况下进行有效测试 提前谢谢 参考图像 第一张图片来自iPhone6模拟器。第二个(正确的一个)来自真实的iPhone6设备。您不会从模拟器中猜到实际设备上的图像是正确的 我们在其他模拟器上也看到了这个问题,比如iPhone7模拟器和iPhoneSE模拟器,所以我们假设这是所有模拟器的问题 此控制器的源代码Ios iPhone模拟器中的图像和真实设备上的图像不一样,ios,xcode,ios-simulator,Ios,Xcode,Ios Simulator,背景 我需要得到一个正方形的图像,以填补一个表单元格边到边,有一个小的空白,并有它的工作在所有设备 我处理不同设备的方法是基于设备以编程方式设置表中的行高,并使用AspectFit使图像填充行——当我知道要将行高设置为什么值时,这种方法很有效。只需几次猜测就可以搞定 问题 图像在模拟器中的显示方式与在真实设备上的显示方式不同,这使得在模拟器上无法进行测试,并要求真实设备具有确定性 这是图像和模拟器的已知问题吗?我是否缺少一些变通方法或设置 我想让模拟器演示与设备演示与图像相匹配,这样我就可以在不
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
…在运行模拟器时,您应该能够选择窗口->像素精度
,然后您可以将屏幕截图保存在相同的尺寸上…这样比较两者就更容易了。