I am trying to swizzle the init methods and layout subviews of UIButton by using the following code:
extension UIButton {
// Swizzled method
@objc func xxx_init(coder aDecoder: NSCoder) {
xxx_init(coder: aDecoder)
}
@objc func xxx_init(frame: CGRect) {
xxx_init(frame: frame)
}
@objc func xxx_layoutSubviews() {
xxx_layoutSubviews()
}
}
And in the app delegate lunch with options method the swizzle of those methods its called:
private func swizzleUIButtonMethods() {
let originalLayout = #selector(UIButton.layoutSubviews)
let newLayout = #selector(UIButton.xxx_layoutSubviews)
swizzleHelper.swizzleMethods(original: originalLayout, new: newLayout, type: UIButton.self)
let originalFrame = #selector(UIButton.init(frame:))
let newFrame = #selector(UIButton.xxx_init(frame:))
swizzleHelper.swizzleMethods(original: originalFrame, new: newFrame, type: UIButton.self)
let originalCoder = #selector(UIButton.init(coder:))
let newCoder = #selector(UIButton.xxx_init(coder:))
swizzleHelper.swizzleMethods(original: originalCoder, new: newCoder, type: UIButton.self)
}
with the helper function being:
func swizzleMethods(original: Selector, new: Selector, type: AnyClass) {
guard let originalMethod = class_getInstanceMethod(type, original),
let newMethod = class_getInstanceMethod(type, new) else {
return
}
let addedMethod = class_addMethod(type, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))
if addedMethod {
class_replaceMethod(type, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, newMethod)
}
}
I'm using Xcode 9.0 and they seem to work well when testing on a real device however when trying to use the simulator the the initialisation of any UIButton crashes the application.
Does anyone know if this is an Xcode/Swift issue or is there something wrong with my approach?
P.S. I'm using Swift 4