替代覆盖扩展的方法

时间:2017-09-27 08:43:43

标签: ios swift swift-protocols swift-extensions

我希望通过添加一些函数来扩展UIView,并在我想要的UIView的任何子类中覆盖它们。我在苹果文档中发现,我无法覆盖扩展(并且编译器会抱怨),这是有道理的。所以

我需要有人建议以下方法:

extension UIView { 
  func hide() { //do almost nothing } 
}

class myLabel: UILabel { 
  override func hide() { 
    //do work on uilabel that can't be done on imgView
  }
}

class myImageView: UIImageView {
 override func hide() { 
    //do work on imgView that can't be done on uilabel
  }
}

我想要这个的原因是我的代码后面会遇到下面的代码而且我需要很多子类而且我不想写太多if-lets试图强制转换{{1} } view

myLabel, myTextView, myImageView... etc

我尝试使用let view = cell.viewWithTag(someTag) // and I want to write this below without casting view.hide() protocols,但我无法做到。

有什么想法吗?

注意:protocol extensions只是一个例子。我的功能还有更多工作要做 **问题更新清楚。

1 个答案:

答案 0 :(得分:2)

编辑:更新答案以使用协议

协议以各种方式确实可以在某些情况下替换子类,但是您仍然需要您的类符合协议才能看到并覆盖这些方法

您可以拥有一个协议,例如:

protocol SomeProtocol {
    func hide()
}

要做你想要做的事情,最好有一个父子类UIView,其中包含所有可以被覆盖的函数(在这个更新的答案中,你可以让你的方法在协议内覆盖并使你的子类符合它):

class ParentView : UIView, SomeProtocol {
    func hide() {
        print("PARENT")
    }

    func anyOtherMethod() {

    }
}

然后让所有其他UIView需要覆盖那些方法子类ParentView

class ViewOne : ParentView {
    override func hide() {
        print("VIEW ONE")
    }
}

class ViewTwo : ParentView {
    override func hide() {
        print("VIEW TWO")
    }
}

所以即使您稍后放置此代码:

let view = cell.viewWithTag(someTag)
// and I want to write this below without casting
view.hide()

您不需要明确地投射您的UIView,视图会将其称为预期的重写方法,除非您在覆盖的方法中调用super

编辑:有关使用协议的更多信息

如果您需要其他控件也要使用hide()方法来覆盖,那么您仍然需要子类化,例如在UILabel的情况下,您需要覆盖它:

class ParentLabel : UILabel, SomeProtocol {
    func hide() {
        print("PARENT LABEL")
    }
}

然后你可以用你的协议编写目标代码

if let view = cell.viewWithTag(someTag) as? SomeProtocol {
    view.hide() // prints PARENT LABEL
}

并且要么使用该子类UILabel控件,要么在某些情况下需要某些标签来覆盖该行为,那么您仍然可以创建ParentLabel的子子类:

class LabelOne : ParentLabel {
    override func hide() {
        print("LABEL ONE")
    }
}