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:
- Navcon titles
- Tab bar titles
- Section index titles
- Alert controllers/action sheets
- 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.