繁体   English   中英

从超类iOS Swift识别子类

[英]Identifying subclass from superclass iOS swift

我有一个BaseViewController ,我的SearchViewController从中SearchViewController 我需要将超类中按钮的目标分配给子类中的方法。 我在超类中有一个名为addBackButton(_:)的方法,该方法将一个按钮添加到navigationView(定制视图)。 我从子类中调用此方法。

我做了什么(代码在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)
    }

我有两个问题:

  1. 超类与子类之间正确的通信方式是什么?
  2. 上面的方法工作正常。 但是,如果我执行'vc is SearchViewController''vc.isKind(of:SearchViewController.self)' ,则两者都可以正常工作。 哪种方法可以从超类中识别出子类?

编辑:

根据anbu.karthiks的评论,我在超类内部使用了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()函数中进行向下转换与面向对象的思想相冲突。

在超类中,您应该放置与所有子类相符的通用代码,如果您需要在特定类中添加一些额外的代码,则应该重写该函数并将特定代码写入特定的子类中,然后调用超类。” functionName”(如果需要)。

在您的代码中,您可以在超类中创建一个名为backButtonTapped()的函数,并在任何子类中覆盖此函数,并编写所需的特定代码。

像这个例子:

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....
    }
}

希望对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM