【问题标题】:How to extend more than one class using Swift 4/5如何使用 Swift 4/5 扩展多个类
【发布时间】:2019-08-02 16:50:15
【问题描述】:

我正在尝试扩展多个类,即 UIButton 和 UITextField。它们都具有相同的功能,当我调用该功能时它们可以摆动。我试图不重复我的代码不止一次。我一直在尝试使用可以扩展并编写我想要的函数然后在我的类中扩展它们的协议,但问题出在我的函数中,我必须调用 self,但我会得到一个错误,因为 self 可以仅在 UITextField 和 UIButton 上调用。

这是我的代码

import UIKit

extension UIButton {

    func wiggle() {
        let position = "position"
        let wiggleAnimation = CABasicAnimation(keyPath: position)
        wiggleAnimation.duration = 0.05
        wiggleAnimation.repeatCount = 5
        wiggleAnimation.autoreverses = true
        wiggleAnimation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
        wiggleAnimation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
        layer.add(wiggleAnimation, forKey: position)
    }

}

extension UITextField {

    func wiggle() {
        let position = "position"
        let wiggleAnimation = CABasicAnimation(keyPath: position)
        wiggleAnimation.duration = 0.05
        wiggleAnimation.repeatCount = 5
        wiggleAnimation.autoreverses = true
        wiggleAnimation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
        wiggleAnimation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
        layer.add(wiggleAnimation, forKey: position)
    }

}

这是我尝试尝试的方法,但由于我正在调用 self,因此出现错误。

protocol Animations {
    func wiggle()
}

extension Animations {
    func wiggle() {
        let position = "position"
        let wiggleAnimation = CABasicAnimation(keyPath: position)
        wiggleAnimation.duration = 0.05
        wiggleAnimation.repeatCount = 5
        wiggleAnimation.autoreverses = true
        wiggleAnimation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
        wiggleAnimation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
        layer.add(wiggleAnimation, forKey: position)
    }
}

extension UIButton: Animations {}

extension UITextField: Animations {}

我收到的错误是 “自我”类型的值没有成员“中心” “自我”类型的值没有成员“中心” 使用未解析的标识符“层”

【问题讨论】:

    标签: ios swift class uikit


    【解决方案1】:

    只有UIView 有中心属性。对于 Swift 5+,您的协议声明应如下所示:

    protocol Animations: UIView {
        func wiggle()
    }
    

    注意只有 UIViews 可以符合这个协议。

    对于 Swift 4.x,你必须像这样使用它:

    protocol Animations {
        func wiggle()
    }
    
    extension Animations where Self: UIView {
       func wiggle() {
            let position = "position"
            let wiggleAnimation = CABasicAnimation(keyPath: position)
            wiggleAnimation.duration = 0.05
            wiggleAnimation.repeatCount = 5
            wiggleAnimation.autoreverses = true
            wiggleAnimation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
            wiggleAnimation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
            layer.add(wiggleAnimation, forKey: position)
        }
    }
    

    【讨论】:

    • 仅供参考,此答案仅适用于 Swift 5+
    • @erdos 我编辑了我的答案并添加了 Swift 4.x 版本。谢谢你的提示。
    【解决方案2】:

    前面给出的答案实际上并没有使用 Swift 4.x 编译,因为协议不能直接从 Swift 5 之前的类继承。

    在 Swift 4.x 中编写此代码的正确方法包括仅当符合类型继承自 UIView 时为您的 wiggle() 函数提供默认实现。正确的写法是:

    protocol Animations {
        func wiggle()
    }
    extension Animations where Self: UIView {
       func wiggle() {
            let position = "position"
            let wiggleAnimation = CABasicAnimation(keyPath: position)
            wiggleAnimation.duration = 0.05
            wiggleAnimation.repeatCount = 5
            wiggleAnimation.autoreverses = true
            wiggleAnimation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
            wiggleAnimation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
            layer.add(wiggleAnimation, forKey: position)
        }
    }
    

    【讨论】:

    • 如何扩展 UIButton 类或其他类?
    • 如果您编写上述协议,您只需扩展任何UIView 继承类以符合它。所以你会写extension UIButton: Animations {}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多