从超类iOS swift中识别子类

时间:2017-05-29 11:20:30

标签: ios swift oop inheritance

我有BaseViewController我的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)',两者都可以正常工作。哪个是从超类中识别子类的正确方法?
  3. 编辑:

    根据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)
        }
    

2 个答案:

答案 0 :(得分:2)

是的,你做的方式工作正常,是一种方法。另一种方法是:

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

超类与子类之间的正确通信方式是什么?

没有什么是对或错,但有些方法比其他方法更好。请查看上面的示例,了解如何执行此操作的一个示例。

答案 1 :(得分:0)

这不是在子类和超类之间进行通信的正确方法, 实际上,这种方法是面向对象的。

在超类中的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....
    }
}

我希望这会有所帮助。