【问题标题】:iOS Different Font Sizes within Single Size Class for Different Devices不同设备的单一大小类中的 iOS 不同字体大小
【发布时间】:2015-03-20 11:48:30
【问题描述】:

在 iOS 8 中,我们可以为每个尺寸等级设计不同的 UI 布局。我面临的问题是,我设计了紧凑宽度和常规高度的布局(所有 iPhone 的纵向尺寸等级),但我想保持 3.5 和 4 英寸设备(iPhone 4 和 5)的标签字体更小),然后 4.7 英寸 (iPhone 6) 相对较大,而 5.5 英寸 (iPhone 6 Plus) 设备则更大。我已经搜索过,但找不到为同一大小类中的不同设备设置不同字体大小的解决方案。

【问题讨论】:

  • “我已经搜索过,但无法找到一种解决方案来为同一大小类中的不同设备设置不同的字体大小。”你是对的——没有简单的解决方案(大概是因为 Apple 并不真的希望你这样做)。如果这对您来说真的很重要,您将不得不使用代码来检测屏幕大小并相应地更改标签的字体大小。
  • 谢谢马特,我只是需要核对一下我的理解。
  • 不过,这并不是一个不合理的想法。您应该向 Apple 提交增强请求。大小类太粗粒度...
  • 你说的很对,我添加了一个最佳解决方案。请在此线程中找到我的答案。我认为它会帮助你:)

标签: ios autolayout font-size size-classes


【解决方案1】:

编辑:我不再推荐这个了。当新设备问世时,这种方法不能很好地扩展。结合使用动态字体大小和特定于大小类别的字体。


假设一个新的 iPhone 型号问世,如果您使用自动布局和大小类,您不必手动修复所有约束以使您的应用与这个新设备兼容。但是,您仍然可以使用以下代码设置UILabel 的字体大小:

if UIScreen.mainScreen().bounds.size.height == 480 {
    // iPhone 4
    label.font = label.font.fontWithSize(20)     
} else if UIScreen.mainScreen().bounds.size.height == 568 {
    // IPhone 5
    label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 375 {
    // iPhone 6
    label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 414 {
    // iPhone 6+
    label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 768 {
    // iPad
    label.font = label.font.fontWithSize(20)
}

【讨论】:

  • 它不会“对 UILabel 起作用”。您只是在更改按钮的大小。这对文本的字体大小没有影响。
  • 如果你想使用它,那么不要对字体使用大小类
【解决方案2】:

两种方式:

1)在appdelegate中手动创建一个方法,共享其对象并调用方法。

例如:

    var device = UIDevice.currentDevice().model

    if (device == "iPhone" || device == "iPhone Simulator" || device == "iPod touch")
        {
            labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width, 1)
            labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width,1)
        }
    else
        {
            labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height, 500, 1)
            labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height, 500,1)
        }

2) 在每个 UI 项目上,转到属性检查器,声明一个字体。

(在字体大小字段左侧有一个+号可见。点击它,选择匹配的大小类并声明字体大小。)

第二个选项对我来说很方便。快乐编码!

【讨论】:

  • 问题是:“如何为同一大小类中的不同设备设置不同的字体大小”。您的评论没有回答这个问题。
  • 你在 iPhone6 Plus 上是怎么做到的? iPhone6 Plus 字体看起来比 iPhone5 小 iPhone5 和 iPhone6Plus Portrain 具有相同的大小类别 h-Companct v-Regular
  • @Maverick:根据设备屏幕大小为 UI 元素设置不同的字体大小不是一个好习惯。文本应该是可读的字体大小并且清晰。请参阅 Apple 的 Human UI 指南。是的,我们可以为不同的大小类别设置不同的字体大小 - 这是推荐的。
【解决方案3】:

您可以达到如下效果。

Usage : 不要使用 14 作为字体大小 你可以使用14.fontSize,它会根据设备而改变,取决于你的增量值。

无需在代码中添加条件 everyWhere。只有一次,如下所示。

用法:UIFont.font_medium(12.fontSize)

UIFont 扩展:

extension UIFont {    
    class func font_medium(_ size : CGFloat) -> UIFont {
        return UIFont(name: "EncodeSans-Medium", size: size)!;
    }    
}

UIDevice 扩展:

extension UIDevice {
    enum DeviceTypes {
        case iPhone4_4s
        case iPhone5_5s
        case iPhone6_6s
        case iPhone6p_6ps
        case after_iPhone6p_6ps
    }

    static var deviceType : DeviceTypes {
        switch UIScreen.main.height {
        case 480.0:
            return .iPhone4_4s
        case 568.0:
            return .iPhone5_5s
        case 667.0:
            return .iPhone6_6s
        case 736.0:
            return .iPhone6p_6ps
        default:
            return .after_iPhone6p_6ps
        }
    }
}

内部扩展:

extension Int{

    var fontSize : CGFloat {

        var deltaSize : CGFloat = 0;
        switch (UIDevice.deviceType) {
        case .iPhone4_4s,
             .iPhone5_5s :
            deltaSize = -1;
        case .iPhone6_6s :
            deltaSize = 2;
        case .iPhone6p_6ps :
            deltaSize = 2;
        default:
            deltaSize = 0;
        }

        let selfValue = self;
        return CGFloat(selfValue) + deltaSize;
    }
}

【讨论】:

    【解决方案4】:

    像这样创建,

    #define VIEWHEIGHT       ([[UIScreen mainScreen] bounds].size.height)
    #define VIEWWIDTH        ([[UIScreen mainScreen] bounds].size.width)
    #define FONTNAME_LIGHT   @"AppleSDGothicNeo-Regular"
    #define FONTNAME_BOLD    @"AppleSDGothicNeo-Bold"
    #define LFONT_16         [UIFont fontWithName:FONTNAME_LIGHT size:16]
    

    在你想改变标签字体之后,我们可以编写简单的 Switch case

    switch ((VIEWHEIGHT == 568)?1:((VIEWHEIGHT == 667)?2:3)) {
        case 1:{
            boldFont = BFONT_16;
        }
            break;
        case 2:{
            privacyFont = LFONT_18;
            boldFont = BFONT_18;
        }
            break;
        default:{
            privacyFont = LFONT_20;
            boldFont = BFONT_20;
        }
            break;
    }
    
    Swift Version
    
    func isPhoneDevice() -> Bool {
        return UIDevice.current.userInterfaceIdiom == .phone
    }
    
    func isDeviceiPad() -> Bool {
        return UIDevice.current.userInterfaceIdiom == .pad
    }
    
    func isPadProDevice() -> Bool {
        let SCREEN_WIDTH = Float(UIScreen.main.bounds.size.width)
        let SCREEN_HEIGHT = Float(UIScreen.main.bounds.size.height)
        let SCREEN_MAX_LENGTH: Float = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
    
        return UIDevice.current.userInterfaceIdiom == .pad && SCREEN_MAX_LENGTH == 1366.0
    }
    
    func isPhoneXandXSDevice() -> Bool {
        let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
        let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
        let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
    
        return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 812.0
    }
    
    func isPhoneXSMaxandXRDevice() -> Bool {
        let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
        let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
        let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
    
        return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 896.0
    }
    

    【讨论】:

      【解决方案5】:

      我在 Swift 3+ 的项目中使用 UILabel 自定义类UILabel 扩展UIDevice 处理它扩展 作为通用解决方案。

      UIDevice 扩展获取screenType:

      public extension UIDevice {
      
          var iPhone: Bool {
              return UIDevice().userInterfaceIdiom == .phone
          }
      
          enum ScreenType: String {
              case iPhone4
              case iPhone5
              case iPhone6
              case iPhone6Plus
              case iPhoneX
              case Unknown
          }
      
          var screenType: ScreenType {
              guard iPhone else { return .Unknown}
              switch UIScreen.main.nativeBounds.height {
              case 960:
                  return .iPhone4
              case 1136:
                  return .iPhone5
              case 1334:
                  return .iPhone6
              case 2208:
                  return .iPhone6Plus
              case 2436:
                  return .iPhoneX
              default:
                  return .Unknown
              }
          }
      
      }
      

      以下是使用screenType 调整字体大小的UILabel 扩展adjustsFontSizeToFitDevice 方法也可以添加到 UILabel 自定义类 中,但我已将它放在 UILabel 扩展 中以使其可从所有类型的 UILabel 实例中访问。

      adjustsFontSizeToFitDevice 方法中使用的常量“2”可以更改为任何所需的数字。我的逻辑是将 iPhone 6/7/8 视为默认分辨率,并为该分辨率的每个标签提供合适的字体大小(在 Storyboard 中)。然后,我为 iPhone X 和 iPhone 6/7/8 Plus 加 2 分,而为 iPhone 4/5 减 2 分。

      extension UILabel {
      
          func adjustsFontSizeToFitDevice() {
      
              switch UIDevice().screenType {
              case .iPhone4, .iPhone5:
                  font = font.withSize(font.pointSize - 2)
                  break
              case .iPhone6Plus, .iPhoneX:
                  font = font.withSize(font.pointSize + 2)
                  break
              default:
                  font = font.withSize(font.pointSize)
              }
          }
      
      }
      

      最后是一个 UILabel 自定义类,用于对从MyCustomLabel 子类化的所有标签应用字体调整。

      class MyCustomLabel: UILabel {
      
          // MARK: - Life Cycle Methods
      
          override func awakeFromNib() {
              super.awakeFromNib()
      
              adjustsFontSizeToFitDevice()
          }
      
      }
      

      用法:Storyboard 中,从MyCustomLabel 子类化所有需要根据设备大小调整字体大小的 UILabel 实例。

      【讨论】:

      • 在stackoverflow上关于同一主题的所有答案中,这要方便得多..但它仍然不完美。因为我需要更改情节提要中的每个标签。我正在寻找解决方案,该解决方案将像上面一样更改字体 ans ...font = font.withSize(font.pointSize + 2) 仅从应用程序中的一个位置(可能来自应用程序委托)的纵向模式下的 iPhone 屏幕尺寸。同时,我不想松散在情节提要中设置的任何字体样式(粗体/常规)。
      【解决方案6】:

      不必为每个标签编写代码,只需使用您的自定义标签类扩展您的标签类,如下所示,它将根据设备分辨率缩放因子自动缩放:

      #define  SCALE_FACTOR_H ( [UIScreen mainScreen].bounds.size.height / 568 )
      
      
      CustomLabel.h
      
      #import <UIKit/UIKit.h>
      
      @interface CustomLabel : UILabel
      
      @end
      
      
      CustomLabel.m
      #import "CustomLabel.h"
      
      @implementation CustomLabel
      
      /*
      // Only override drawRect: if you perform custom drawing.
      // An empty implementation adversely affects performance during animation.
      - (void)drawRect:(CGRect)rect {
          // Drawing code
      }
      */
      - (id)initWithCoder:(NSCoder *)aDecoder {
          if( (self = [super initWithCoder:aDecoder]) ){
              [self layoutIfNeeded];
              [self configurefont];
          }
          return self;
      }
      
      - (void) configurefont {
          CGFloat newFontSize = (self.font.pointSize * SCALE_FACTOR_H);
          self.font = [UIFont fontWithName:self.font.fontName size:newFontSize];
      }
      @end
      

      【讨论】:

        【解决方案7】:

        我就是这样做的。它是用 Swift 4 编写的 :)

        enum DeviceSize {
            case big, medium, small
        }
        
        protocol Fontadjustable {
        
            var devicetype: DeviceSize { get }
        
            func adjustFontSizeForDevice()
        }
        
        extension UILabel: Fontadjustable {
        
            var devicetype: DeviceSize {
                switch UIScreen.main.nativeBounds.height {
                case 1136:
                    return .small
                case 1334:
                    return .medium
                case 2208:
                    return .big
                case 2436:
                    return .big
                default:
                    return .big
                }
            }
        
            func adjustFontSizeForDevice() {
                switch self.devicetype {
                case .small:
                    self.font = font.withSize(font.pointSize)
                case .medium:
                    self.font = font.withSize(font.pointSize + 5)
                case .big:
                    self.font = font.withSize(font.pointSize + 10)
                }
            }
        }
        

        用法:myawesomeLabel.adjustFontSizeForDevice()

        【讨论】:

        • 这需要更多的爱。这是一个非常可靠的解决方案。感谢分享。
        猜你喜欢
        • 2015-10-29
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多