我试图通过使用以下代码来调用UIButton的init方法和布局子视图:
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()
}
}
在应用程序委托午餐和选项方法中,这些方法的混合称为:
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)
}
辅助函数为:
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)
}
}
我正在使用Xcode 9.0,它们在真实设备上进行测试似乎运行良好,但是当尝试使用模拟器时,任何UIButton的初始化都会使应用程序崩溃。
有谁知道这是Xcode / Swift问题还是我的方法有问题?
P.S。我正在使用Swift 4