我的方案阻止我子类化
class Button: UIButton {
override open func layoutSubviews() { // I cannot do this
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2
}
}
我的方案阻止我使用常量和此方案。不,我不能在MyView
中覆盖layoutSubviews
,这只是为了给示例一个上下文。
class MyView: UIView {
let buttonHeight: CGFloat = 50
lazy var button: UIButton = ...
func setupSubViews() { // I cannot do this either..
button.addConstraint(button.heightAnchor.constraint(equalToConstant: buttonHeight))
button.layer.cornerRadius = buttonHeight / 2
}
}
我想要的(不可能? 😬不,我不能在MyView
中覆盖layoutSubviews
,这只是为了给示例一个上下文。
class MyView: UIView {
lazy var button: UIButton = ...
func setupSubViews() {
// desired solution, using some closure that will be run when layouting
button.whenLayout { button, boundsWhenLayout in
button.layer.cornerRadius = boundsWhenLayout.height / 2
}
}
}
有没有办法做我想做的事?我再说一遍,我不能对身高进行子类化,也不能使用常数。我不能在拥有UIButton的视图/视图控制器中使用layoutSubview。我想要一个通用的解决方案。
也许使用Objective-C方法以某种方式旋转?或者也许使用一些转换
这个呢:
private let swizzling: (AnyClass, Selector, Selector) -> () = { forClass, originalSelector, swizzledSelector in
let originalMethod = class_getInstanceMethod(forClass, originalSelector)
let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
method_exchangeImplementations(originalMethod, swizzledMethod)
}
extension UIButton {
public func startSwizzle() {
let originalSelector = #selector(layoutSubviews)
let swizzledSelector = #selector(swizzled_layoutSubviews)
swizzling(UIButton.self, originalSelector, swizzledSelector)
}
func swizzled_layoutSubviews() {
swizzled_layoutSubviews()
print("swizzled_layoutSubviews ", self.frame)
}
}
这是 UIButton 的扩展,它添加了一个 startSwizzle 方法,该方法在调用时将在实际类版本之前执行 swizzled_layoutSubviews((。