保留泛型类型以供以后重用

问题描述 投票:0回答:1

我想要的是: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
类型?

谢谢

swift generics
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.