简体   繁体   中英

Setting app-wide default font that allows for varying sizes

I'd like to have all the text in my app show up in Oswald font. I've seen great answers that involve things like UILabel.appearance().font = yourFont . However, as far I can tell this requires constructing a font using UIFont(name:_size:_) which, of course, takes a size argument. This means that different labels that should be different sizes (like title and subtitle text in a Subtitle-style table cell) all show up at the same size.

Is there a simple way to set the font for the whole app once, and allow the sizes on different objects to be their standard size?

Supplemental questions: 1. What are the UITextView / UITextField equivalents of UILabel.appearance().font ? UITextView.appearance().font doesn't appear to exist. 2. Is there a way in these app-wide statements to also effect things like Navigation Bar title fonts and Table Section Header fonts?

I've found a very good though not completely comprehensive solution.

Most of my views are tables of one sort or another, so I've done the following (note: I'm omitting the FontNames struct which includes a function to get bold/ital/light variations. also, big thanks to https://stackoverflow.com/a/44921262/6826164 for the subviews function.

extension UITableViewController {

open override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    for view in subviewsOf(view) {
        setFont(for: view)
    }
}

fileprivate func subviewsOf<T: UIView>(_ view: UIView) -> [T] {
    var subviews = [T]()

    for subview in view.subviews {
        subviews += subviewsOf(subview) as [T]

        if let subview = subview as? T {
            subviews.append(subview)
        }
    }
    return subviews
}

fileprivate func setFont(for view: UIView) {

    if let label = view as? UILabel {
        label.font = UIFont(name: FontNames.fontName(), size: label.font.pointSize)
    }
    else if let textField = view as? UITextField, let font = textField.font {
        textField.font = UIFont(name: FontNames.fontName(light: true), size: font.pointSize)
    }
    else if let textView = view as? UITextView, let font = textView.font {
        textView.font = UIFont(name: FontNames.fontName(light: true), size: font.pointSize)
    }
        // Technically this button font setting is unnecessary since the titleLabel will be covered as a UILabel in the view heirarchy,
        // but this allows a separate font for buttons if desired
    else if let button = view as? UIButton, let label = button.titleLabel {
        button.titleLabel!.font = UIFont(name: FontNames.fontName(), size: label.font.pointSize)
    }

}

}

There's a number of things this doesn't cover, of course, including:

  1. Navcon titles
  2. Tab bar titles
  3. Section index titles
  4. Alert controllers/action sheets
  5. Any other VCs that aren't Tables, obviously.

Any thoughts/tips on being more comprehensive, including other specific views I'm likely to encounter that aren't accounted for here (not counting the catchall #5 of course)? I've tried solutions mentioned in the comments and haven't quite been able to make any of them work as well as this one.

Also, any thoughts on a better place to put this besides viewDidLayoutSubviews since that one gets called at random? I've tried putting it in viewWillAppear but that doesn't work for some reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM