【问题标题】:Correct Image and Font Scale on different Devices?在不同设备上正确的图像和字体比例?
【发布时间】:2015-08-11 09:46:09
【问题描述】:

我有一个带有文本和图像的简单视图。我在 iPhone6Plus 和 iPhone5 上运行了这个应用程序。然后我制作了两者的屏幕截图并放大了 iPhone5 屏幕截图,使其与 iPhone6Plus 屏幕截图的大小相匹配。结果如下:

由于您可以设置文本的大小,因此图像的大小和位置并不相同,但它们在不同的屏幕尺寸上应该看起来相同。

下面是weather app 在不同屏幕上运行的示例:

如您所见,文本和图像的大小和位置是相同的。

图片是从资产目录加载的:

imageView.image = UIImage(named: "shower3")
self.view.addSubView(imageView)
imageView.center = self.view.center

我只创建了一个 128x128 的图像,并将其放入资产目录中的 @1x 版本中。

让我重新表述一下。我在 iPhone5 上运行应用程序进行截图,然后在 iPhone6 上进行截图。然后我将两个屏幕截图调整为相同大小。然后我看到两个屏幕截图上的字体大小和图像尺寸都完全相同。这意味着每个设备上的字体和图像必须具有不同的尺寸。我怎样才能做到这一点?

我怎样才能使文字和图像在不同的屏幕尺寸上具有相同的比例? Weather App 是怎么做到的?

【问题讨论】:

  • 您是否创建了@3x 版本的图像?
  • 不,我只有@1x 版本。如天气应用程序:github.com/JakeLin/SwiftWeather
  • 请发布您正在使用的代码,或列出您的限制条件。

标签: ios objective-c iphone swift autolayout


【解决方案1】:

iOS 使用points 来计算图像和字体大小。在非视网膜屏幕上,1 点等于 1 像素,在视网膜屏幕上 — 2 像素,而对于 iPhone 6 Plus,它等于 3 像素(不过,应用了一些缩小比例)。如果你想根据屏幕的实际像素大小来缩放图像和字体,你可以像这样得到每点的像素数:

CGFloat screenScale = [[UIScreen mainScreen] scale];

iPhone 5、6 和 6 Plus 的屏幕纵横比相同,但分辨率不同。如果您想简单地保持比例,那么您必须选择一个“基本”屏幕宽度或高度(例如,iPhone 5 屏幕宽度,即 320.0 点),然后通过除以实际设备屏幕宽度来计算比例(例如, iPhone 6 Plus 屏幕宽度,即 414.0 点)乘以“基本”宽度(414.0 / 320.0 = 1.29375)。你可以像这样得到屏幕尺寸:

CGRect screenBounds = [[UIScreen mainScreen] bounds];

screenBounds 的宽度除以基本宽度即可得出比例。然后,您只需将所有尺寸和边距乘以该比例(在我们的 iPhone 6 Plus 案例中为 1.29375)。希望你能明白。

附: here 是一个很好的解决方案指南。

P.P.S.在您的情况下,正如下面提到的 skorolkov,该应用程序只是为更大的屏幕升级所有内容(添加/删除启动屏幕以启用/禁用此升级)。

UPD: 好的,现在我知道是什么让你感到困惑了。事情是这样的:当 Apple 最初发布 iPhone 6 和 6 Plus 时,许多应用程序不支持其更大的屏幕和更大的分辨率。因此他们决定,如果某个应用缺少为这些手机制作的专门启动画面,则应使用 iPhone 5 分辨率。

这就是为什么您在手动调整屏幕截图大小后得到完全相同的图片的原因:系统也会这样做。它只需要 iPhone 5 的“图片”并拉伸它以适应更大的屏幕。缺点很明显(并且可见,尤其是在 iPhone 6 Plus 上):字体和图像模糊且放大了(系统界面元素,如状态栏,也被放大了)。所以基本上你可以在所有大屏幕设备上获得 iPhone 5 图片(你可以通过在 iPhone 5 上截屏来检查,手动调整大小以适应 iPhone 6/6 Plus 分辨率并比较实际iPhone 6/6 Plus 截图)。

要明确:这是您目前得到的行为,但这并不好。要使用设备的原始分辨率正确缩放所有内容,请使用我上面描述的方法(手动乘法)或将equal height/width 设置为界面元素所需比率的自动布局。

【讨论】:

  • 通过适当的情节提要设置完成。如果你不明白,你需要阅读一些关于自动布局和界面生成器的书籍/教程。
  • 你能解释一下这个应用程序作为故事板设置的作用吗?使用 InterfaceBuilder 时如何实现相同的效果?
  • 你可以从这里开始:raywenderlich.com/50317/…
  • 我仍然知道自动布局的工作原理,但我不明白天气应用程序中的字体和图像如何在不同的屏幕上调整大小。
【解决方案2】:

如果屏幕的纵横比相同,您需要为所有视图设置布局约束,以使它们在所有屏幕尺寸下都可以看到相同的位置和尺寸。

【讨论】:

  • 请发布一个示例如何制作这个!
  • 您是否阅读了这些问题。问题是如何制作相同比例的图像和字体。
【解决方案3】:

您是否尝试从视图中删除 autoResizingfunctionality? 单击内部箭头以删除 autoResize 按照 superview 的视图

【讨论】:

    【解决方案4】:
    1. 首先关闭情节提要中的自动布局、自动调整大小和大小类。
    2. 单击 Images.xcassets 图标并选择所有图形。在属性检查器中,将 Devices 属性设置为“特定于设备”,并设置针对“iPhone”和“Retina 4-inch”选中的复选框
    3. 将所有图形放置在 2x 图像集中。您可以使用 iPhone 6/6+ 放置更高分辨率的图像集以获得更好的效果。
    4. 为参考设备设计您的视图,例如 iPhone 5(320x568 纵向)。
    5. 在您的 viewDidLoad 方法中粘贴以下代码

    self.view.transform=CGAffineTransformScale(CGAffineTransformIdentity,self.view.frame.size.width/320, self.view.frame.size.height/568);

    你会在 iPhone 5/5s、iPhone 6/6+ 上得到相同的结果。

    【讨论】:

    • 让我重新表述一下。我在 iPhone5 上运行应用程序进行屏幕截图,然后在 iPhone6 上进行屏幕截图。然后我将两个屏幕截图调整为相同大小。然后我看到两个屏幕截图上的字体大小和图像尺寸都完全相同。这意味着每个设备上的字体和图像必须具有不同的尺寸。我该怎么做?
    【解决方案5】:

    您所指的应用程序不正确支持多种屏幕尺寸。该界面已按比例放大以在 6 和 6 plus 上运行,这就是为什么所有内容都显示为相同大小的原因。

    查看您应用的屏幕截图 - 6 plus 上的状态栏要小得多。这是因为应该在屏幕上占用更少的空间。在所有设备上都是 20 分。

    现在看一下天气应用程序的屏幕截图 - 状态栏的大小相同。因为天气应用程序不支持多种屏幕尺寸,iOS 只是采用较小的界面并将其放大以填满屏幕。

    如果您想获得相同的效果(您不应该这样做),请删除 LaunchScreen.xib 文件并改用启动图像。但人们不会购买更大的电话屏幕,因为他们希望拥有相同的内容,但更大。只需将手机靠近一个人的脸,就可以更便宜地实现这一点。

    您应该通过允许在屏幕上一次显示更多内容来利用更大的显示器 - 表格中的更多数据行、书籍中的更多文本、照片库中的更多图像。

    对于天气应用程序,应该使用额外的空间来显示更多行的每小时预报或其他内容,而不仅仅是描述天气类型的相当无用的图标的放大版本。

    我怀疑只是游戏支持意味着正确支持更大的屏幕并不是应用商店提交的要求。支持 4 英寸屏幕很快就成为强制性的,您应该期待很快就会为 6 和 6 plus 引入类似的规则。

    如果您希望特定元素始终占据屏幕宽度的 50%,或者希望标签始终与图像大小相同,那么您可以将自动布局约束与 multipliers 结合使用。自动布局约束具有基本结构:

    attribute of A = (attribute of B * multiplier) + constant
    

    大多数情况下,乘数保留为 1,因此您只是说这是在其左侧 20 点,或者其他什么,但您也可以使用乘数,并说 A 是宽度B,乘以 2 或 0.5 或任何你喜欢的。

    【讨论】:

    • 但我怎样才能实现比例相等而与屏幕尺寸无关?
    • 您可以在不同视图之间添加带有乘数的约束(因此 A 是 B 宽度的两倍或其他)
    • 这个等式不正确。实际上是:attribute of A = multiplier * attribute of B + constant。见developer.apple.com/library/content/documentation/…
    • @Tricky gosh,这些年来,你是第一个注意到的!谢谢,我会修改
    【解决方案6】:

    天气应用程序正在使用高档模式在 iPhone 6+ 上运行。您可以通过删除 6/6+ 的启动屏幕来启用它。

    转到资产目录,选择您的启动图像并取消设置属性检查器中的“iOS 8 或更高版本”复选框。

    Screenshot - your app has this set

    Screenshot from WeatherApp

    【讨论】:

      【解决方案7】:

      图片

      我是Swift Weather app 的创建者和开发者之一。该应用程序不使用三个版本的图像,因为这些图像不是我制作的,而且它是来自另一个开发人员的拉取请求。我没有原始图像。

      正如@Daniil Korotin 提到的,iOS 使用points 来计算图像和字体大小。 iOS 使用let screenScale = UIScreen.mainScreen().scale 来检索屏幕比例并选取适当尺寸(1x、2x 或 3x)的图像。如果我们没有提供合适的图片尺寸,例如,在 SwiftWeather 应用中,我们只有 1x 版本的图片(如下图所示),iOS 会放大图片以在视网膜设备上渲染。在 iPhone 6 Plus 上,它实际上对 3 倍资产进行了下采样。请查看iPhone 6 Screens Demystified。在某些情况下,如果您不提供 2x 或 3x 图像,在视网膜设备上,从 1x 放大的图像可能看起来模糊。如果可能,我们应该始终提供 1x、2x 和 3x 图像。

      字体

      iOS 根据指定的points 渲染字体。它会根据设备的屏幕比例(如上所述)自动将点转换为特定像素。

      我怎样才能让文字和图像在不同的屏幕尺寸上具有相同的比例?天气应用是如何做到的? 答案是自动布局

      您可以看到我们为图像视图(用于天气图标)设置了约束,如下所示。 宽度和高度始终为 150 points,请注意它是 pointspixels。它将为不同的设备呈现相同的大小(对于外观,而不是完全像素)。对于您的第一张图片(iPhone 6 Plus 与 iPhone 5),它看起来不同,因为您的模拟器可能具有不同的规模。检查自动布局元素如何在屏幕上放置的更好方法是使用 Interface Builder 中的 Preview。

      打开主故事板,然后单击助理编辑器。在右侧,选择预览(在左上角)。然后单击加号(左下角)添加不同的设备。你可以看到它们在不同的屏幕尺寸上是相同的比例。

      如果您有任何问题,请告诉我。

      有些东西可能跑题了

      如果我设计图像/资产,我想使用像 Sketch 这样的矢量基础工具来设计资产并将它们导出为三种不同的尺寸。请看看我的另一个项目iOSAnimationSample。它有一个设计草图文件。

      素描设计

      将资产导出为不同大小

      在这种情况下,iOS 可以为不同的设备选择合适的资产。

      【讨论】:

      • 让我重新表述一下。我在 iPhone5 上运行应用程序进行屏幕截图,然后在 iPhone6 上进行屏幕截图。然后我将两个屏幕截图调整为相同大小。然后我看到两个屏幕截图上的字体大小和图像尺寸都完全相同。这意味着每个设备上的字体和图像必须具有不同的尺寸。我该怎么做?
      • 它们没有不同的尺寸。在 Iphone5 上,一个点映射到 2 个像素,在 iphone6 上,一个点映射到 3 个像素。所以这就是为什么它们在点方面具有相同的尺寸。 IOS 处理的是点而不是像素。
      • @stephan1001as M Abdul Sami 说,他们有相同的观点。并渲染到不同的像素。对于字体,它是基于矢量的,与像素无关。对于图像,它会自动拾取正确的图像(1x、2x 或 3x)或放大 1x 以适应。请让我知道您觉得不清楚的部分,我可以更新答案。
      • @stephan1001你能看看stackoverflow.com/questions/12019170/…我可能还是不明白你的困惑是什么。
      【解决方案8】:

      在编程方式(X 和 Y)中,我们预先定义常量中的值:

      #define XScale [[UIScreen mainScreen] bounds].size.width / 320.0f
      #define YScale [[UIScreen mainScreen] bounds].size.height / 568.0f
      

      然后以编程方式创建 UIImageView

      var imageView : UIImageView
      imageView  = UIImageView(frame:CGRectMake(XScale *someValue, YScale * someValue, XScale *someValue, YScale *someValue));
      imageView.image = UIImage(named:"image.jpg")
      self.view.addSubview(imageView)
      

      根据您的屏幕尺寸,我们需要设置常量值。我们用于 iPhone5 和 4s 屏幕。

      【讨论】:

      • 让我重新表述一下。我在 iPhone5 上运行应用程序进行截图,然后在 iPhone6 上进行截图。然后我将两个屏幕截图调整为相同大小。然后我看到两个屏幕截图上的字体大小和图像尺寸都完全相同。这意味着每个设备上的字体和图像必须具有不同的尺寸。我该怎么做?
      • 嗨@stephan1001 它的尺寸与设备不同。所以我们可以指定自动布局或以编程方式定义它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 2018-01-30
      • 2015-08-14
      • 1970-01-01
      • 2020-08-16
      相关资源
      最近更新 更多