多重继承的替代方案在Swift中是什么?

3

我有一个类,使用'frame'来管理UIKit元素的位置:

class EasyPos: UIView {
    var screenWidth = UIScreen.main.bounds.width
    var screenHeight = UIScreen.main.bounds.height

    var x: CGFloat = 0          { didSet { self.updateFrame() } }
    var y: CGFloat = 0          { didSet { self.updateFrame() } }
    var width: CGFloat = 0      { didSet { self.updateFrame() } }
    var height: CGFloat = 0     { didSet { self.updateFrame() } }

    func updateFrame() {
        frame = CGRect(x: x, y: y, width: width, height: height)

        if x < 0 {
            frame = CGRect(x: screenWidth - abs(x) - width, y: frame.minY, width: frame.width, height: frame.height)
        }
        if y < 0 {
            frame = CGRect(x: frame.minX, y: screenHeight - abs(y) - height, width: frame.width, height: frame.height)
        }
    }

    required init(x: CGFloat = 0, y: CGFloat = 0, width: CGFloat = 40, height: CGFloat = 40) {

        self.x = x
        self.y = y
        self.width = width
        self.height = height

        super.init(frame: .zero)

        updateFrame()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

现在我想添加一个继承自UIButton的类和一个继承自UILabel的类。它们都应该能够使用EasyPos类的方法。我该怎么做?(我尝试过从两个类进行继承,但不起作用)
我知道这与协议有关,但我也无法使其起作用。
谢谢您的帮助 ;)

1
UIView 创建一个 extension - Harsh
1个回答

2

您可以通过编写协议扩展来实现此功能。由于您具有属性,因此需要实现一个组件,但这不应该太困难。

struct FrameComponent {
    var x: CGFloat = 0         
    var y: CGFloat = 0          
    var width: CGFloat = 0      
    var height: CGFloat = 0
}

protocol EasyPos {
    var fc: FrameComponent { get, set }
    func updateFrame()
}

extension EasyPos where Self: UIView {
     func updateFrame() {
        frame = CGRect(x: fc.x, y: fc.y, width: fc.width, height: fc.height)

        if fc.x < 0 {
            frame = CGRect(x: screenWidth - abs(fc.x) - fc.width, y: frame.minY, width: 
              frame.width, height: frame.height)
        }
        if fc.y < 0 {
            frame = CGRect(x: frame.minX, y: screenHeight - abs(fc.y) - fc.height, width: 
              frame.width, height: frame.height)
        }
    }
}

需要记住的一点是,扩展程序无法添加属性观察器,因此您需要手动调用updateFrame()


当我在我的类中添加“var fc:FrameComponent { didSet { update()} }”时,它不起作用,因为出现了“Property 'self.fc' not initialized at super.init call”的错误。您能帮我将您的解决方案实现到这个类中吗? - swift-lynx
2
不需要通过创建FrameComponent结构体来重新发明CGRect。 - CodeBender
1
谢谢,我只需在类中添加“var fc:FrameComponent = FrameComponent(){ didSet { updateFrame()} }”,就可以让它正常工作了。 - swift-lynx
是的,抱歉,我同意@CodeBender的观点。 - Chris Edgington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接