覆盖扩展方法的替代方法
Alternative to override extension's method
我想通过添加一些函数来扩展 UIView
,并在我想要的 UIView
的任何子类中覆盖它们。我在 apple 文档中发现我无法覆盖某些有意义的扩展(并且编译器会抱怨)。所以
我需要有人建议以下替代方法:
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
试图投射 view
到 myLabel, myTextView, myImageView... etc
let view = cell.viewWithTag(someTag)
// and I want to write this below without casting
view.hide()
我试过 protocols
和 protocol extensions
但我没能成功。
有什么想法吗?
注意:func hide()
只是一个例子。我的 func 将有更多工作要做。
**问题已更新为清楚。
编辑: 更新答案以也使用协议
协议确实以各种方式使您能够在某些情况下替换 subclassing,但是您仍然需要 class 符合协议才能看到和覆盖这些方法
你可以有一个协议,例如:
protocol SomeProtocol {
func hide()
}
要做你打算做的事情,最好有一个父子class UIView,其中包含所有可以被覆盖的功能(例如,在这个更新的答案中,你可以让你的方法在协议并让你的 subclasses 遵守它):
class ParentView : UIView, SomeProtocol {
func hide() {
print("PARENT")
}
func anyOtherMethod() {
}
}
然后让所有其他 UIView 需要覆盖这些方法 subclass 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()
方法来重写,那么您仍然可以使用 subclass,例如在 UILabel 的情况下您需要重写它:
class ParentLabel : UILabel, SomeProtocol {
func hide() {
print("PARENT LABEL")
}
}
然后您可以通过转换为您的协议来编写预期的代码
if let view = cell.viewWithTag(someTag) as? SomeProtocol {
view.hide() // prints PARENT LABEL
}
并使用子classed UILabel 控件,或者如果您在某些情况下需要一些标签来覆盖该行为,那么您仍然可以创建 ParentLabel
的子子 class :
class LabelOne : ParentLabel {
override func hide() {
print("LABEL ONE")
}
}
我想通过添加一些函数来扩展 UIView
,并在我想要的 UIView
的任何子类中覆盖它们。我在 apple 文档中发现我无法覆盖某些有意义的扩展(并且编译器会抱怨)。所以
我需要有人建议以下替代方法:
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
试图投射 view
到 myLabel, myTextView, myImageView... etc
let view = cell.viewWithTag(someTag)
// and I want to write this below without casting
view.hide()
我试过 protocols
和 protocol extensions
但我没能成功。
有什么想法吗?
注意:func hide()
只是一个例子。我的 func 将有更多工作要做。
**问题已更新为清楚。
编辑: 更新答案以也使用协议
协议确实以各种方式使您能够在某些情况下替换 subclassing,但是您仍然需要 class 符合协议才能看到和覆盖这些方法
你可以有一个协议,例如:
protocol SomeProtocol {
func hide()
}
要做你打算做的事情,最好有一个父子class UIView,其中包含所有可以被覆盖的功能(例如,在这个更新的答案中,你可以让你的方法在协议并让你的 subclasses 遵守它):
class ParentView : UIView, SomeProtocol {
func hide() {
print("PARENT")
}
func anyOtherMethod() {
}
}
然后让所有其他 UIView 需要覆盖这些方法 subclass 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()
方法来重写,那么您仍然可以使用 subclass,例如在 UILabel 的情况下您需要重写它:
class ParentLabel : UILabel, SomeProtocol {
func hide() {
print("PARENT LABEL")
}
}
然后您可以通过转换为您的协议来编写预期的代码
if let view = cell.viewWithTag(someTag) as? SomeProtocol {
view.hide() // prints PARENT LABEL
}
并使用子classed UILabel 控件,或者如果您在某些情况下需要一些标签来覆盖该行为,那么您仍然可以创建 ParentLabel
的子子 class :
class LabelOne : ParentLabel {
override func hide() {
print("LABEL ONE")
}
}