2

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?

Jonathan Tuzman
  • 11,568
  • 18
  • 69
  • 129
  • 1
    Possible duplicate of [Using custom font for entire iOS app swift](https://stackoverflow.com/questions/28180449/using-custom-font-for-entire-ios-app-swift) – Shehata Gamal Jan 21 '18 at 20:43
  • Check out https://stackoverflow.com/questions/8707082/set-a-default-font-for-whole-ios-app – trndjc Jan 22 '18 at 00:11

1 Answers1

0

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.

Jonathan Tuzman
  • 11,568
  • 18
  • 69
  • 129