iPhone Increase font size for larger devices

2020-07-28 07:28发布

问题:

I have simple app that has some views to show. It is portrait app so I do not have to build any other design for orientation specific.

But I have one trouble(Being new on iOS), I have read about size classes and yet I am unable to understand that How I can mange to increase size of a text/Label per device.

What I have done:

I mean I am testing on following mobiles

  1. iPhone 5s
  2. iPhone 8plus
  3. iPhone XR

I have a label inside a view and that label has 18 points as a text size or font size

What I want:

I want that my font must be gradually increase on large devices such as iPhone XR and iPad and decrease on smaller devices such as iPhone 5s

Question: I want to do following but I do not know how to do it even with size classes because as far as I understood Size classes is related to orientations the most, may be I am wrong but this is I extracted from my readings

I want that on following phone, text size must be something like these

  1. iPhone 5s --> Text Size 12
  2. iPhone 8Plus --> Text Size 18
  3. iPhone XR --> Text Size 19
  4. iPadPro 12 inch --> Text Size 32

Please let me know how to achieve that ?

Note: I want to do it with out coding I mean in interface builder

回答1:

To solve your case . you need to identify the user device modal.

enum DeviceModals : String {
    //iphones
    case iPhone5s_GSM = "iPhone6,1"
    case iPhone5s_China_Gobal = "iPhone6,2"
    case iPhone6_Plus = "iPhone7,1"
    case iPhone6 = "iPhone7,2"
    case iPhone6S = "iPhone8,1"
    case iPhone6S_Plus = "iPhone8,2"
    case iPhoneSE = "iPhone8,4"
    case iPhone7_CDMA = "iPhone9,1"
    case iPhone7_GSM = "iPhone9,3"
    case iPhone7_Plus_CDMA = "iPhone9,2"
    case iPhone7_Plus_GSM = "iPhone9,4"
    case iPhone_8_CDMA =   "iPhone10,1"
    case iPhone_8_GSM =  "iPhone10,4"
    case iPhone_8_Plus_CDMA =  "iPhone10,2"
    case iPhone_8_Plus_GSM =  "iPhone10,5"
    case iPhone_X_CDMA = "iPhone10,3"
    case iPhone_X_GSM =  "iPhone10,6"
    case iPhone_XS = "iPhone11,2"
    case iPhone_XS_Max =   "iPhone11,4"
    case iPhone_XS_Max_China = "iPhone11,6"
    case iPhone_XR =   "iPhone11,8"
    case iPhone_11 =   "iPhone12,1"
    case iPhone_11_Pro =  "iPhone12,3"
    case iPhone_11_Pro_Max =  "iPhone12,5"

    //iPad
   case iPad_Air_wifi_5Gen  =  "iPad4,1"
   case iPad_Air_cellular_5Gen =  "iPad4,2"
   case iPad_Mini_wifi_2Gen = "iPad4,4"
   case iPad_Mini_cellular_2Gen = "iPad4,5"
   case iPad_Mini_wifi_3rd_Gen =  "iPad4,7"
   case iPad_Pro_12_9_A1584 =  "iPad6,7"
   case iPad_Pro_12_9_A1652 =  "iPad6,8"
   case iPad_Pro_9_7_A1673 =  "iPad6,3"
   case iPad_Pro_9_7_A1674 =  "iPad6,4"

    case otherDevice = "other"

}
extension UIDevice {
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        return identifier
    }
    func deviceModal() -> DeviceModals{
        let deviceName  = UIDevice.current.modelName
        let deviceModal = DeviceModals(rawValue: deviceName) ?? DeviceModals.otherDevice
        return deviceModal
    }
}

If you support the Accessibility feature in your app. Users will have a controller for text Size in your app.

Settings -> Display&brightness -> Text Size .

This default size will change for different devices based on device size.

    extension UIFont
    {
    // A scale value based on the current device text size setting.    With the device using the default Large setting, `scaler` will be `1.0`. Only used when `UIFontMetrics` is not available.
        var scaler: CGFloat {
            return UIFont.preferredFont(forTextStyle:.body).pointSize/17.0
         }
       func scaledFont() -> UIFont {
            if #available(iOS 11.0, *) {
                return UIFontMetrics.default.scaledFont(for: self)
            } else {
                return self.withSize(scaler * self.pointSize)
            }
        }
    }

You can button font now.

UILabel().font = UIFont.systemFont(ofSize: 12).scaledFont() 

Now you knew which device users have, So you can create one custom Label (or) Button (or) AnyComponent with text data.

class CustomLabel : UILabel{

    override func awakeFromNib() {
        super.awakeFromNib()
        let deviceModal = UIDevice.current.deviceModal()
        var font_size : CGFloat = 18
        switch deviceModal {
        case .iPhone5s_GSM , .iPhone5s_China_Gobal  :
            font_size = 12
        case .iPhone_8_Plus_CDMA , .iPhone_8_Plus_GSM:
           font_size = 18
        case .iPhone_XR:
            font_size = 19
        default:
            font_size = 18
        }
        self.font = UIFont.systemFont(ofSize: font_size).scaledFont()
    }
}

In your storyboard select your label, go to the right corner and select custom class and put "CustomLabel".Now you don't have to write any other code it will work perfectly.

I hope your issue is solved now.



回答2:

Size classes will not help you with this.

There are 2 ways to do this:

  1. Custom sizing You can have some function that returns size or multiplayer, based on the current device. Then you would manually set font size returned from the function, or use the multiplayer to get the size based on some default size.
  2. Maximum or minimum font size of Label You can configure the Autoshrink setting of you label to have Minimum font size. This can be done through Interface Builder.