替代扩展的方法

Ahm*_*thi 5 ios swift swift-extensions swift-protocols

我想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
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要这个的原因是,稍后在我的代码中我将面对下面的代码,并且我有很多子类,并且我不想编写太多if-lets尝试将其转换viewmyLabel, myTextView, myImageView... etc

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

我尝试过protocolsprotocol extensions但我做不到。

有什么想法吗?


注意:func hide()这只是一个例子。我的功能还有更多工作要做。
**问题已更新以明确。

Azh*_*Ali 2

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

协议确实以多种方式允许您在某些情况下替换子类化,但是您仍然需要您的类符合协议才能查看和覆盖这些方法

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

protocol SomeProtocol {
    func hide()
}
Run Code Online (Sandbox Code Playgroud)

要执行您打算执行的操作,最好有一个父子类 UIView ,其中包含可以覆盖的所有功能(在这个更新的答案中,您可以让您的方法在协议内部覆盖并让您的子类符合它):

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

    func anyOtherMethod() {

    }
}
Run Code Online (Sandbox Code Playgroud)

然后让所有其他 UIView 需要重写这些方法子类ParentView

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

class ViewTwo : ParentView {
    override func hide() {
        print("VIEW TWO")
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,即使您稍后放置此代码:

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

您不需要显式转换您的 UIView,视图将调用它的预期重写方法,除非并且直到您super也调用您的重写方法

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

如果您需要其他控件也有一个hide()方法来重写,那么您仍然需要子类化,例如在 UILabel 的情况下,您需要重写它:

class ParentLabel : UILabel, SomeProtocol {
    func hide() {
        print("PARENT LABEL")
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以通过转换为您的协议来编写预期的代码

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

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

class LabelOne : ParentLabel {
    override func hide() {
        print("LABEL ONE")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不用担心,只要它对你有用,如果你也能选择我的答案那就太好了,你也可以编辑你的修改 (2认同)