2017-06-15 54 views
0

我的情況防止我從繼承執行`layoutSubviews`繪製_without_繼承視圖,而不是使用閉包?

class Button: UIButton { 
    override open func layoutSubviews() { // I cannot do this 
     super.layoutSubviews() 
     layer.cornerRadius = bounds.height/2 
    } 
} 

我的情況防止我使用常量和這個場景。並且我不能覆蓋layoutSubviewsMyView,它只是給這個例子一個上下文。

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 
    } 
} 

我想要什麼(不可能的?)。而沒有我不能覆蓋MyViewlayoutSubviews,它只是給了一個例子:語境

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的view/viewcontroller中使用layoutSubview。我想要一個通用的解決方案

也許使用Objective-C 方法swizzling莫名其妙?或者,也許使用一些改造

+0

您可以覆蓋MyView的layoutSubviews方法並更新按鈕。 –

+0

@UpholderOfTruth抱歉,不清楚。我無法訪問該視圖。我僅僅是一個給出背景的例子。我無法使用任何子類。我需要一個通用的解決方案,它需要能夠應用change_without_訪問layoutSubviews。 – Sajjon

+0

你的意思是你沒有訪問MyView(你的例子),在這種情況下你將如何訪問按鈕本身? –

回答

0

這個怎麼樣:

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()的時候。