Где это может пригодиться? Везде, где требуется изменить лейбл в контролах, не дающих это сделать. UIDatePicker, как пример. А дизайн требует!
В данном примере мы заменим шрифт UILabel внутри пикера:
extension UILabel {
@objc func setFontSwizzled(font: UIFont) {
if self.shouldOverride() {
guard let rubikMedium = R.font.rubikMedium(size: 22) else { return }
self.setFontSwizzled(font: rubikMedium)
}
else {
self.setFontSwizzled(font: font)
}
}
private func shouldOverride() -> Bool {
let classes = ["UIDatePicker", "UIDatePickerWeekMonthDayView", "UIDatePickerContentView"]
var view = self.superview
while view != nil {
let className = NSStringFromClass(type(of: view!))
if classes.contains(className) {
return true
}
view = view!.superview
}
return false
}
private static let swizzledSetFontImplementation: Void = {
let instance = UILabel()
let aClass: AnyClass! = object_getClass(instance)
let originalMethod = class_getInstanceMethod(aClass, #selector(setter: font))
let swizzledMethod = class_getInstanceMethod(aClass, #selector(setFontSwizzled))
if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
// Switch implementation..
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}()
static func swizzleSetFont() {
_ = self.swizzledSetFontImplementation
}
}
Использовать можно так:
@IBOutlet private(set) weak var datePicker: UIDatePicker! {
didSet {
let locale = Locale(identifier: "ru_RU")
datePicker.locale = locale
datePicker.setValue(R.color.mainViolet(), forKey: "textColor")
datePicker.setValue(false, forKey: "highlightsToday")
UILabel.swizzleSetFont() // <==================
datePicker.minimumDate = Date().adding(years: -50)
datePicker.maximumDate = Date()
}
}
Что в итоге?