代码之家  ›  专栏  ›  技术社区  ›  Luke

两个类使用相同的函数创建自定义视图-Swift

  •  0
  • Luke  · 技术社区  · 6 年前

    value 这需要在函数内部传递。我不想在每个类中重复setUpStackView函数的相同代码。我有以下代码:

    class Class1: UIStackView {
    
        var variable1 = "value1"
    
        override init(frame: CGRect){
          super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder){
          super.init(coder: aDecoder)
        }
    
        setUpStackView(value: variable1)
    
    }
    
    class Class2: UIStackView {
    
        var variable2 = "value2"
    
        override init(frame: CGRect){
          super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder){
          super.init(coder: aDecoder)
        }
    
        setUpStackView(value: variable2)
    
    }
    
    
    
    
    extension Class1 {
    
      func setUpStackView(value: String){
        //code to set UIStackView rating control and to use the variable value
      }
    
    }
    

    我如何实现应用程序的扩展 Class2 ? 我被这件事缠住了。任何帮助都将不胜感激!

    1 回复  |  直到 6 年前
        1
  •  2
  •   halfer Jatin Pandey    6 年前

    一种解决方案可以将通用代码移动到协议中,您可以从中提取:

    protocol  BaseStackView {
        var variable :String { get set }
    }
    
    class Class1: UIStackView,BaseStackView {
    
    
    
        var variable = "value1"
    
        override init(frame: CGRect){
          super.init(frame: frame)
            self.setUpStackView(value: variable)
    
        }
    
        required init(coder: NSCoder) {
            super.init(coder: coder)
            self.setUpStackView(value: variable)
        }
    }
    
    class Class2: UIStackView,BaseStackView {
    
        var variable = "value2"
    
        override init(frame: CGRect){
          super.init(frame: frame)
            self.setUpStackView(value: variable)
        }
    
        required init(coder: NSCoder) {
            super.init(coder: coder)
            self.setUpStackView(value: variable)
        }
    
    
    
    }
    
    
    
    extension UIStackView {
        func setUpStackView(value: String) {
            //Your setup here
        }
    }
    
        2
  •  1
  •   Xavier L.    6 年前

    你有很多选择。

    class Class2: Class1 {
        var value = "value2" //You have access to Class1's value, so you can change it here
        setUpStackView(value: value) //But there's a problem here
    }
    

    但是,不能在类声明的中间调用函数。 但您可以在初始值设定项中执行此操作:

    class Class2: Class1 {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            value = "value2" 
            setUpStackView(value: value) 
        }
    
        required init(coder aDecoder: NSCoder){
            super.init(coder: aDecoder)
            value = "value2"
            setUpStackView(value: value) 
        }
    }
    

    上面的内容有点僵硬,因为您正在引用其自身初始值设定项中的类属性。 下面是另一个解决方案:

    您可以将设置功能设置为UIStackView的功能扩展:

    extension UIStackView {
        func setUpStackView(value: String) { 
            //Your setup here
            self.someProperty = value //self is referring to the stackview itself
        }
    }
    

    另一个选项是创建静态函数。

    extension Class1 {
        static func setUpStackView(stackVw: UIStackView, value: String) {
            stackVw.someProperty = value 
            //Doing it like this still makes this function "belong" to Class1
            //It also makes it so anyone can set up their stack view like
            //this because they have to pass their stack view in here
        }
    }
    

    无论您在哪个类中,也不管您有什么继承层次结构,使用情况都是这样的:

    override init(frame: CGRect) {
        super.init(frame: frame)
        Class1.setUpStackVw(stackVw: self, value: self.variable)
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        Class1.setUpStackVw(stackVw: self, value: self.variable)
    }
    

    还有一个选择是创建一个协议,Class1和Class2都符合该协议。

    protocol StackVwWithSpecialSetUp where Self: UIStackView {
        var value: String {get}
    }
    extension StackVwWithSpecialSetUp {
        func setUpStackView() 
        {
            self.someProperty = self.value
        }
    }
    

    然后你会让你的班级遵守它

    class Class1Or2: UIStackView, StackVwWithSpecialSetUp {
        var value: String = "blah" //Compiler will force you to implement this
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            //Now you can use this
            setUpStackVw()
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            //You can use this here too
            setUpStackVw()
        }
    }
    

    也许我会这样做,只是不需要 value 财产合计:

    class Class1: UIStackView {
        override init(frame: CGRect) {
            super.init(frame: frame)
            setUpStackVw()
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setUpStackVw()
        }
    
        func setUpStackVw()
        {
            self.accessibilityHint = "value1"
        }
    }
    
    //////////
    
    class Class2: Class1 {
        override func setUpStackVw()
        {
            self.someProperty = "value2"
        }
    }