[英]Swift - override a method in two subclasses of UIView
我正在使用UITextField
和UIButton
自定義子類MyTextField
和MyButton
。
在這兩種方式中,我都是通過以下方式創建圓角的邊緣:
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.使用擴展名,因為UIButton
和UITextField
都是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.