Ios 从超类中识别子类
我有一个Ios 从超类中识别子类,ios,swift,oop,inheritance,Ios,Swift,Oop,Inheritance,我有一个BaseViewController,从中我的SearchViewController是子类。我需要将超类中按钮的目标分配给子类中的方法。我在超类中有一个名为addBackButton(:)的方法,它在navigationView(定制视图)中添加了一个按钮。我从子类调用这个方法 func addBackButton() { let button = UIButton(type: .custom) button.frame = CGRect(x: 10,
BaseViewController
,从中我的SearchViewController
是子类。我需要将超类中按钮的目标分配给子类中的方法。我在超类中有一个名为addBackButton(:)
的方法,它在navigationView(定制视图)中添加了一个按钮。我从子类调用这个方法
func addBackButton() {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
button.tintColor = currentTheme.navButtonTintColor
switch self {
case is SearchViewController:
let controller: SearchViewController = self as! SearchViewController
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
break
case is HelpViewController:
let controller: HelpViewController = self as! HelpViewController
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
break
default:
break
}
navigationBarView.addSubview(button)
}
我所做的(代码在swif 3中):
上面的方法接受一个viewcontroller对象,我通过将self
传递给该方法,从子类调用它,这样它就可以正常工作了。方法定义如下:
func addBackButton(from vc: AnyObject) {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
button.tintColor = currentTheme.navButtonTintColor
if vc.isKind(of:SearchViewController.self) {
let controller: SearchViewController = self as! SearchViewController
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
}
navigationBarView.addSubview(button)
}
我有两个问题:
'vc是SearchViewController'
和'vc.isKind(of:SearchViewController.self)
,这两种方法都可以正常工作。从超类中识别子类的正确方法是什么 func addBackButton() {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
button.tintColor = currentTheme.navButtonTintColor
switch self {
case is SearchViewController:
let controller: SearchViewController = self as! SearchViewController
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
break
case is HelpViewController:
let controller: HelpViewController = self as! HelpViewController
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
break
default:
break
}
navigationBarView.addSubview(button)
}
是的,你做这件事的方法很好,而且是一种方法。另一种方法是:
if let controller = vc as? SearchViewController {
// use controller in here which is casted to your class and ready to be used
}
因此,您的代码:
func addBackButton(from vc: AnyObject) {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
button.tintColor = currentTheme.navButtonTintColor
if let controller = vc as? SearchViewController {
button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
}
navigationBarView.addSubview(button)
}
超类与子类之间的正确通信方式是什么
没有什么是对的或错的,但是有些方法比其他的好。查看我上面的示例,了解如何执行此操作。这不是子类和超类之间通信的正确方法, 事实上,这种方法是反面向对象的 在位于超类中的
addBackButton()
函数中执行向下转换与面向对象的思想相冲突
在超类中,您应该放置与所有子类兼容的通用代码,如果您需要向特定类添加一些额外的代码,您应该重写该函数,并将指定代码写入特定子类,并在需要时调用super.“functionName”
在代码中,可以在名为backbuttoncapped()的超类中创建一个函数
并在任何子类中重写此函数,并编写所需的特定代码
像这个例子:
class SuperClass: UIViewController {
let navigationBarView = UINavigationBar()
func addBackButton(from vc: AnyObject) {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
button.tintColor = .white
button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
navigationBarView.addSubview(button)
}
@objc func backButtonTapped() {
//every subClass will override this funcion and handle it
}
}
class Subclass: SuperClass {
override func backButtonTapped() {
//Do your specific code....
}
}
我希望这是有帮助的。是的,正确…,简单的自我识别子类很好谢谢@Anbu.Karthik。我的想法很复杂。我删除了函数参数,只是在超类中使用了一个开关
self
,工作正常。谢谢@Rashwan。你能像我一样使用is
关键字来识别超类吗?我已经编辑了这个问题。请看一看。