【问题标题】:Size class to identify iPhone 6 and iPhone 6 plus portrait识别 iPhone 6 和 iPhone 6 plus 纵向的尺寸等级
【发布时间】:2015-01-19 20:50:46
【问题描述】:

如何使用尺寸等级唯一标识 iPhone 6 和 iPhone 6 plus 竖屏?

我的应用在 iPhone 4 和 iPhone 5 中看起来不错,但在 iPhone 6 和 6 plus 中看起来相同,但由于屏幕尺寸的原因有很多空白。虽然我正在使用自动布局,但我不能只为 iPhone 6 和 6 plus 增加字体大小或视图大小。我知道我们可以使用大小类来更改字体大小和视图大小。但就我而言,不知道该怎么做。

我正在使用 xCode 6.1,我的应用支持从 iOS 7 到最新的 iOS 8.1。我只在故事板中期待解决方案,就像我在故事板中完全做我的 UI 设计一样。如果故事板的功能有限,无法满足我的需求,请让我知道如何通过应用程序的代码实现相同的功能?

【问题讨论】:

  • 就尺寸等级和设备类型而言都是一样的。如果您正确地进行自动布局,则视图大小将随着屏幕比例的变化而变化。您能否展示一下为什么需要不同字体大小的屏幕截图?
  • @matt 您可以在此处查看适用于 iPhone 6 plus 的文件。由于保密协议,我无法分享真实版本。我只需要每个标签之间的间隙,并且我确实有一些控件。 dropbox.com/s/ycar93s6j8djv33/…
  • 感谢您的屏幕截图,但您认为它有什么问题?
  • @matt 要求所有屏幕尺寸都具有相同的布局。因此,如果屏幕尺寸增加,那么我的标签尺寸和标签到文本字段的间隙需要自动增加。 :( 到目前为止,尺寸与较小的尺寸相同。
  • “要求是所有屏幕尺寸都具有相同的布局”这是一个愚蠢的“要求”。这里的整个理念是适应以适应不断变化的多种屏幕尺寸。这就是为什么关于这个主题的 WWDC 视频都是关于适应的。说“相同的布局”与适应相反。这是古板。 :) 如果您不想适应,那就见鬼,只包括 iPhone 4s 的启动图像,让自己放大 iPhone 6 型号。您将拥有完全相同相同的界面。

标签: ios ios8 xcode6 xcode-storyboard


【解决方案1】:

根据 iPhone 类型调整字体大小的另一个选项是使用“用户定义的运行时属性”。

定义 UILabel 的扩展:

extension UILabel {
    var adjustFontToRealIPhoneSize: Bool {
        set {
            if newValue {
                var currentFont = self.font
                var sizeScale: CGFloat = 1
                let model = UIDevice.CurrentDevice().modelName()

                if model == "iPhone 6" {
                    sizeScale = 1.3
                }
                else if model == "iPhone 6 Plus" {
                    sizeScale = 1.5
                }

                self.font = currentFont.fontWithSize(currentFont.pointSize * sizeScale)
            }
        }

        get {
            return false
        }
    }
}

为了确定当前的型号名称,请参考以下回答:https://stackoverflow.com/a/26962452/4165128

在情节提要上,选择您要调整的标签,打开右侧窗格,选择身份检查器,然后将“adjustFontToRealIPhoneSize”属性添加到用户定义的运行时属性列表中(类型为“布尔”并选中复选框) .

对您希望调整的每个标签执行相同的操作(复制和粘贴在这里非常有效)。

【讨论】:

  • 您可以将@IBInspectable 添加到该扩展,然后您可以直接从属性检查器中对其进行编辑。
  • 谁能提供它的 Objective-C 版本?
  • 我不认为确定精确模型是针对多尺寸设备的(甚至是预期的)方法。
  • 字符串比较模型名称不是一个好主意(说得好)。您应该使用尺寸等级。检查各种尺寸的尺寸等级以确定要使用的尺寸字体。例如,请参阅我的答案。
【解决方案2】:

在情节提要中使用紧凑宽度和常规高度

通过添加乘数添加相对于超级视图的高度和宽度的布局约束。 假设您的图像视图大小为超级视图的一半,然后添加乘数 0.5。

【讨论】:

  • 能否请您多解释一下乘数或提供一些链接以阅读它?
  • 到目前为止,我已经设置了您在图片中提到的尺寸等级。但是对于 iPhone 6 plus,我的字体看起来太小了。
  • 但我的问题是字体大小和其他控件之间的差距。假设我有一个间隔为 10 的标签和文本字段。它在较小的屏幕上看起来不错,但在较大的屏幕上它会一样,所以我可以看到很多空白空间。有什么方法可以识别和更改控件之间的字体大小和间距?
  • 感谢您的回答。我为我的问题添加了一个屏幕截图到 cmets。请查看它以了解我的需求。
  • 帮了我一把。谢谢!
【解决方案3】:

查看adjustsFontSizeToFitWidth @UILabel Class Reference。这将允许您根据不同的设备进行一些不错的调整。

label.adjustsFontSizeToFitWidth = YES;

【讨论】:

    【解决方案4】:

    我对不同 iPhone 设备中不同字体大小的 sizeClass 没有太多了解,但我想出了这个解决方案。

    1. 将此方法添加到您的实用程序类中。
    2. 只需将您的超级视图传递给此方法,此方法是递归的,因此如果您传递 self.view,则设置所有子视图。
    3. 根据需要更改字体大小。
    -(void)setAllFonts:(UIView *)view
    {
    
    CGFloat fontSizeDiff = 0.0;
    
    if (IS_IPHONE_6)
    {
        fontSizeDiff = 1;
    }
    else if (IS_IPHONE_6PLUS)
    {
        fontSizeDiff = 2;
    }
    
    for (UIView *vw in [view subviews])
    {
        if ([vw isKindOfClass:[UILabel class]] || [vw isKindOfClass:[UIButton class]])
        {
            if ([vw isKindOfClass:[UILabel class]])
            {
                UIFont *font = [(UILabel *)vw font];
                [(UILabel *)vw setFont:[UIFont fontWithName:font.fontName size:font.pointSize+fontSizeDiff]];
            }
            else
            {
                UIFont *font = [(UIButton *)vw titleLabel].font;
                [(UIButton *)vw titleLabel].font = [UIFont fontWithName:font.fontName size:font.pointSize+fontSizeDiff];
            }
        }
        else if ([vw isKindOfClass:[UIView class]] || [vw isKindOfClass:[UIScrollView class]])
        {
            [self setAllFonts:vw];
        }
    }
    }
    

    【讨论】:

    • “我对不同 iPhone 设备中不同字体大小的 sizeClass 没有太多了解” ...这是您应该停止的地方,并学习如何使用大小类而不是放入黑客。此代码如何处理 iPhone 7、8、iPad Pro 等...?
    【解决方案5】:

    @iBhaviks 的 Swift 版本回答:

    func getFontScaleForDevice() -> CGFloat {
        var sizeScale = CGFloat(1.0)
        if DeviceType.IS_IPHONE_6 {
            sizeScale = 1.2
        } else if DeviceType.IS_IPHONE_6P {
            sizeScale = 1.4
        } else if DeviceType.IS_IPAD {
            sizeScale = 1.4
        }
        return sizeScale
    }
    
    func setAllFonts(targetView:UIView, scale:CGFloat) {
        for vw in targetView.subviews {
            if let vl = vw as? UILabel {
                vl.font = vl.font.fontWithSize(round(vl.font.pointSize * scale))
            } else if let vb = vw as? UIButton, vbl = vb.titleLabel {
                vbl.font = vbl.font.fontWithSize(vbl.font.pointSize * scale)
            } else if vw.subviews.count > 0 {
                setAllFonts(vw, scale: scale)
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let sizeScale = getFontScaleForDevice()
        if sizeScale > CGFloat(1.0) {
            setAllFonts(view, scale: sizeScale)
        }
        view.layoutIfNeeded()
    }
    

    【讨论】:

    • 请不要鼓励与特定型号进行比较。此代码将在一年内破解。学习正确使用 Apple 预期的尺寸等级。
    【解决方案6】:

    也许您可以为大屏幕设置完美的字体大小,然后将Autoshrink 设置为适合小屏幕的完美大小的minimum font size,这样您就可以拥有动态字体大小而无需编码。

    无论如何,您都必须为标签设置约束以根据屏幕大小调整其大小。

    希望有帮助

    【讨论】:

    • 但是如果文本换行(超过一行),自动收缩不起作用。
    • 如果是多行标签,那么解决方案可能需要一些代码。如果没有,那么我认为这是一个不错的选择
    【解决方案7】:

    经过很多努力,我找到了一些适合我需要的东西,所以为未来的读者发布了相同的东西。

    1. 到目前为止,还没有办法使用 Size 类来唯一识别 iPhone 6 型号的肖像。但是,您可以使用紧凑的宽度和常规的高度来设计所有 iPhone 的纵向屏幕
    2. 要更改字体大小,您必须使用代码确定应用程序当前在哪个 iPhone 上运行,并根据该代码设置字体大小
    3. 对于我的要求 - 所有屏幕尺寸的布局相同 - 在宽度和高度约束中使用乘数。查看 Jignesh 对这个问题的回答以了解更多信息。

    编辑 2015 年 9 月 24 日 我最近找到了一种方法来自定义您的尺寸等级,仅针对 iPhone 6 plus 使用UITraitColleection,因此您无需编写太多代码。我希望这个link 将来会帮助某人。

    【讨论】:

    • 但是如果我们还想支持 iPhone 的横向模式,使用 UITraitColleection 的方式将无济于事。
    【解决方案8】:

    这有点晚了,但我需要一个可以扩展到任何设备并使用这种方法的标签。

    创建一个新的 UILabel 子类,并在 .h 文件中放入这个…

    #import <UIKit/UIKit.h>
    
    IB_DESIGNABLE
    
    @interface OTHD_ScalableLabel : UILabel
    
    @property (nonatomic, assign) IBInspectable CGFloat fontScale;
    
    @end
    

    然后在 .m 文件中放这个……

    #import "OTHD_ScalableLabel.h"
    
    @implementation OTHD_ScalableLabel
    
    - (void) layoutSubviews
    {
        [super layoutSubviews];
    
        if( self.fontScale < 0.1 || self.fontScale > 1.0 )      self.fontScale = 1.0;
    
        CGFloat height = CGRectGetHeight(self.bounds) * self.fontScale;
    
        if( height )        self.font = [UIFont fontWithName:self.font.fontName size:height];
    }
    
    
    @end
    

    然后您可以在 IB 中更改您的课程,并使用 IBInspectable 您将能够放大或缩小标签。显然,对于那些迂腐的人来说,这对于一般用途来说不是一个好主意,但在某些情况下,您可能需要一个在 iPhone 上显示全屏以及在 iPad 上全屏显示的大标签。

    【讨论】:

      【解决方案9】:

      下面是我用来在运行时切换两种不同字体大小的函数示例。它根据水平尺寸类别决定使用哪种字体 - 这基本上将设备分为两组“iPad”和“iPhone”。以下是关于哪些设备属于哪些尺寸类别的一个很好的参考:http://useyourloaf.com/blog/size-classes/

      • iPad 及以上
      • iPhone Plus 和 Down
       func chooseFont(compactFont: UIFont, regularFont: UIFont) -> UIFont {
          let appDelegate = UIApplication.shared.delegate as! AppDelegate
          return appDelegate.window!.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.compact ? compactFont : regularFont
      }
      

      【讨论】:

        【解决方案10】:

        根据您的屏幕截图,我建议使用动态类型。这样,用户负责文本的大小。

        【讨论】:

        • 所以你的意思是说作为开发人员我不需要关心字体大小和控件之间的间隙。所以我的应用在大屏幕上看起来会有很多空隙,这肯定会影响用户体验。
        • 为什么会有“很多空白”?这就是自动布局的作用。
        猜你喜欢
        • 2015-08-04
        • 2015-09-04
        • 1970-01-01
        • 1970-01-01
        • 2014-11-28
        • 2015-01-31
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多