如何重构我的代码以避免重复

时间:2018-07-11 13:47:57

标签: swift uibutton uilabel refactoring extension-methods

我有一个修改UILabel文本并对其进行处理的函数。 这样做,我在UILabel扩展中创建了我的函数。 完美地工作

extension UILabel {

   let replaced = self.text.doSomething()

   func animate() {

      UIView.transition(with: self, duration: duration,options:[], animations: {
        self.text = replaced
      }

   }    
}

我需要完全相同的东西,只是UIButton的文本。

有没有一种方法可以不重复UIButton Extension中的相同代码?

3 个答案:

答案 0 :(得分:2)

如何制定协议?

protocol AnimationProtocol {}

class SomeUIButton: UIButton, AnimationProtocol {}

class SomeUILabel: UILabel, AnimationProtocol {}

extension AnimationProtocol {

   let replaced = self.text.doSomething()

   func animate() {

      UIView.transition(with: self, duration: duration,options:[], animations: {
        self.text = replaced
      }

   }    
}

答案 1 :(得分:0)

一种可行的方法是制定协议并创建可在类型之间使用的通用属性

import UIKit

protocol textSettable: class {
    var textValue: String { get set }

    func doSomething() -> String
    func animate()
}

extension textSettable where Self: UIButton {
    var textValue: String? {
        get {
            return self.titleLabel?.text
        }
        set {
            self.titleLabel?.text = newValue
        }
    }
}

extension textSettable where Self: UILabel {
    var textValue: String? {
        get {
            return self.text
        }
        set {
            self.text = newValue
        }
    }
}

extension textSettable {

    func doSomething() -> String {
        return String(textValue.reversed())
    }

    func animate() {
        UIView.transition(with: self, duration: duration,options:[], animations: {
             self.text = doSomething()
        }
    }
}

这样,您可以“修饰”您要使用的每种类型的文本值。

答案 2 :(得分:0)

第一部分是UILabel和UIButton都具有文本属性。

protocol TextProtocol: class {
    var text: String? { get set }
}
extension UIButton: TextProtocol {
    var text: String? {
        get {
            return self.titleLabel?.text
        } set {
            self.titleLabel?.text = newValue
        }
    }
}
extension UILabel: TextProtocol {}

第二部分建立在第一部分的基础上,并确保UILabel和UIButton都具有animate(text:duration:)函数。

protocol AnimatableTextProtocol: TextProtocol where Self: UIView {}
extension AnimatableTextProtocol {
    func animate(text: String, duration: TimeInterval) {
        UIView.transition(with: self, duration: duration, options: [], animations: { 
            self.text = text
            })
    }
}
extension UILabel: AnimatableTextProtocol {}
extension UIButton: AnimatableTextProtocol {}

注意:如果您从TextProtocol中删除class,则动画函数将其self视为不可变的,因为值类型也将能够从协议继承。通过class部分,AnimatableTextProtocol知道它可以与使self可变的引用类型一起使用,从而可以将文本属性分配给它。

func yeah(button: UIButton, label: UILabel) {
    button.text = "hello"
    label.text = "world"

    button.animate(text: "hello2", duration: 0.5)
    label.animate(text: "world", duration: 1.5)
}