执行“布局子视图”绘图_不_子类化视图,改用闭包



我的方案阻止我子类化

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((。

最新更新