You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 5中如何在Storyboard中使用UIFontMetrics?能否借助@IBInspectable与@IBDesignable实现?

Using @IBDesignable and @IBInspectable for Dynamic Custom Font Scaling in Storyboard

Absolutely! This is exactly the kind of scenario where @IBDesignable and @IBInspectable shine—they let you configure dynamic, custom font scaling directly in Storyboard, so you don’t have to write repetitive code for every label. Here’s a step-by-step solution tailored to your needs:

Step 1: Create a Custom UILabel Subclass

Make a reusable label class that handles the dynamic font logic and exposes configurable properties to Storyboard:

import UIKit

@IBDesignable
class DynamicCustomFontLabel: UILabel {
    
    // Configurable in Storyboard Attributes Inspector
    @IBInspectable var customFontName: String = "AvenirNext-Regular" {
        didSet { updateFont() }
    }
    
    @IBInspectable var defaultFontSize: CGFloat = 18.0 {
        didSet { updateFont() }
    }
    
    // Map string values to UIFont.TextStyle (e.g., "body", "headline")
    @IBInspectable var textStyleName: String = "body" {
        didSet { updateFont() }
    }
    
    private var textStyle: UIFont.TextStyle {
        switch textStyleName.lowercased() {
        case "largetitle": return .largeTitle
        case "title1": return .title1
        case "title2": return .title2
        case "title3": return .title3
        case "headline": return .headline
        case "subheadline": return .subheadline
        case "body": return .body
        case "callout": return .callout
        case "footnote": return .footnote
        case "caption1": return .caption1
        case "caption2": return .caption2
        default: return .body
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLabel()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupLabel()
    }
    
    private func setupLabel() {
        // Enable automatic adjustment for system font size changes
        adjustsFontForContentSizeCategory = true
        updateFont()
    }
    
    private func updateFont() {
        // Try to load the custom font, fall back to system font if it's missing
        guard let baseFont = UIFont(name: customFontName, size: defaultFontSize) else {
            font = UIFontMetrics(forTextStyle: textStyle).scaledFont(for: .systemFont(ofSize: defaultFontSize))
            return
        }
        // Apply dynamic scaling based on the specified text style
        font = UIFontMetrics(forTextStyle: textStyle).scaledFont(for: baseFont)
    }
    
    // Refresh font when the user changes system font size
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        guard traitCollection.preferredContentSizeCategory != previousTraitCollection?.preferredContentSizeCategory else { return }
        updateFont()
    }
}

Step 2: Use the Custom Label in Storyboard

  1. Drag a standard UILabel onto your Storyboard.
  2. In the Identity Inspector, set the label’s class to DynamicCustomFontLabel.
  3. Switch to the Attributes Inspector—you’ll see three new configurable properties:
    • Custom Font Name: Enter your custom font’s exact name (e.g., "AvenirNext-Regular")
    • Default Font Size: Set your base font size (18.0 in your example)
    • Text Style Name: Enter the text style you want to use for scaling (e.g., "body", "headline")

Key Notes

  • Font Installation: Make sure your custom font is properly added to your project (include it in your target and add it to the Fonts provided by application array in Info.plist).
  • Live Preview: Since this is @IBDesignable, you’ll see the scaled font directly in Storyboard as you adjust properties.
  • Dynamic Type Support: The label will automatically update its font size when the user changes their system text size settings.

内容的提问来源于stack exchange,提问作者JongChan Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:47:33