我正在使用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,但你必须在每个布局中调用 roundTheCorner 自定义类的底层。 仅供参考:https://docs.swift.org/swift-book/LanguageGuide/Extensions.html
B.使用运行时添加自定义属性round
,然后使用方法重排替换方法布局子图层。 这可能有点棘手。仅供参考: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)