我想要的是:UIKit 中的 SwiftUI 风格
.padding
方法。
我尝试过的:
class Padding<T: UIView>: UIView {
var base: T { viewToPad }
let defaultPadding: UIEdgeInsets = .init(top: 8, left: 12, bottom: 8, right: 12)
private var viewToPad: T
init(view: T, padding: UIEdgeInsets? = nil) {
self.viewToPad = view
self.viewToPad.translatesAutoresizingMaskIntoConstraints = false
super.init(frame: .zero)
addSubview(viewToPad)
self.viewToPad.attachToContainer(side: .top, constant: padding?.top ?? defaultPadding.top)
self.viewToPad.attachToContainer(side: .bottom, constant: padding?.bottom ?? defaultPadding.bottom)
self.viewToPad.attachToContainer(side: .left, constant: padding?.left ?? defaultPadding.left)
self.viewToPad.attachToContainer(side: .right, constant: padding?.right ?? defaultPadding.right)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension UIView {
func padded<T: UIView>(with padding: UIEdgeInsets? = nil) -> Padding<T> {
return Padding(view: self as! T, padding: padding)
}
}
我的问题:我无法使
base
成为实际的 T
类型:
let label = UILabel(text: "Instructions").padding()
label.base.textColor = UIColor.black // Value of type 'UIView' has no member 'textColor'
label.base
在这里是 UIView
类型。有没有办法让 base
成为 UILabel
类型?
谢谢
padded
应该返回 Padding<Self>
,而不是泛型,但它不能在 UIView
的扩展中直接执行此操作。您可以通过引入协议并扩展该协议来解决此问题。
protocol Paddable: UIView {}
extension UIView: Paddable {}
extension Paddable {
func padded(with padding: UIEdgeInsets? = nil) -> Padding<Self> {
return Padding(view: self, padding: padding)
}
}
现在这是可能的:
let label = UILabel().padded()
label.base.textColor = UIColor.black