簡體   English   中英

Swift-在UIView的兩個子類中重寫一個方法

[英]Swift - override a method in two subclasses of UIView

我正在使用UITextFieldUIButton自定義子類MyTextFieldMyButton

在這兩種方式中,我都是通過以下方式創建圓角的邊緣:

var round = true
override func layoutSublayers(of layer: CALayer) {
    super.layoutSublayers(of: layer)
    layer.cornerRadius = round ? self.frame.height/5.0 : 0
}

我試圖找到一種通用的方法來使兩個類都具有round字段並覆蓋layoutSublayers(...) 有什么比在每個類中粘貼相同的代碼更好的方法呢?

另外,如果您想使用一種非常靈活的方法,則可以使用視圖樣式概念。 這是您可以從以下開始的簡單實現:

typealias Style<T> = (T) -> Void

extension UIView {

    convenience init<V: UIView>(with styles: [Style<V>]) {
        self.init(frame: .zero)
        guard let view = self as? V else {
            assertionFailure("Could not apply style for \(V.self) to \(type(of: self))")
            return
        }
        styles.forEach { $0(view) }
    }
}

然后聲明一些樣式表

enum ViewStyle {

    static func rounded(radius: CGFloat) -> Style<UIView> {
        return { view in
            view.layer.cornerRadius = radius
            view.clipsToBounds = true
        }
    }

    static let lightGray: Style<UIView> = { view in
        view.backgroundColor = .lightGray
    }
}

並像這樣使用

let button = UIButton(with: [ViewStyle.rounded(radius: 5.0)])
let textField = UITextField(with: [
    ViewStyle.rounded(radius: 8.0),
    ViewStyle.lightGray
])

它將允許您重用預定義的樣式並將其混合以實現更復雜的設置,而無需創建自己的自定義子類。 當然,這只是可以做的一小件事,我鼓勵您更進一步:)

A.使用擴展名,因為UIButtonUITextField都是UIView的子類,您可以嘗試使用func roundTheCorner()方法對UIView進行擴展,但是必須在自定義類的每個layoutSublayers中調用roundTheCorner。 僅供參考: https : //docs.swift.org/swift-book/LanguageGuide/Extensions.html

B.使用運行時添加自定義屬性round ,然后使用swizzling方法替換方法layoutSublayers。 這可能有點棘手。 僅供參考: https : //nshipster.com/method-swizzling/

也許最簡單的方法是在UIButton和UITextField都繼承自UIView的類上編寫擴展。

extension UIView {
    func roundCorners(_ round: Bool) {
      layer.cornerRadius = round ? self.frame.height/5.0 : 0
     }
}

然后在兩個子類的某個地方調用它

roundCorners(true)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM