如何将事件从UIView公开到UIViewController

时间:2016-07-12 16:06:12

标签: swift swift2

我有一个UIView,代码如下:

import UIKit


class ServiceAuthHeaderViewController: UIView {


    @IBOutlet var lblHeaderTitle: UILabel!
    @IBOutlet var btnAddService: UIButton!

    class func instanceFromNib() -> UIView {
        return UINib(nibName: "ServiceAuthHeaderView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
    }

    @IBAction func onAddService(sender: AnyObject) {
        // I want other UIViewControllers to know when this event ocurrs

    }
}

现在我有一个UIViewController,我在其中创建了一个UIView的实例:

  var headerView = ServiceAuthHeaderViewController.instanceFromNib()
        headerView. // here I want to attach the onAddService event.

有关如何做到这一点的任何线索?

  

欣赏它

2 个答案:

答案 0 :(得分:1)

有多种方法可以做到。

使用委托模式。

您可以创建协议,然后在视图控制器中实现它:

protocol ServiceAuthHeaderViewDelegate {
    func onAddService(sender: AnyObject)
}

class ServiceAuthHeaderView: UIView {
    var delegate: ServiceAuthHeaderViewDelegate?

    @IBOutlet var lblHeaderTitle: UILabel!
    @IBOutlet var btnAddService: UIButton!

    class func instanceFromNib() -> UIView {
        return UINib(nibName: "ServiceAuthHeaderView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
    }

    @IBAction func onAddService(sender: AnyObject) {
        delegate?.onAddService(sender)
    }
}

class MyViewController: UIViewController, ServiceAuthHeaderViewDelegate {
    var myServiceAuthHeaderView: ServiceAuthHeaderView?

    // some initialization function
    func initViews() {
        myServiceAuthHeaderView?.delegate = self
    }

    func onAddService(sender: AnyObject) {
        // handling of the callback.
    }
}

使用闭包作为回调

class ServiceAuthHeaderView: UIView {
    var onAddServiceCallback: ((sender: AnyObject) -> Void)?

    @IBOutlet var lblHeaderTitle: UILabel!
    @IBOutlet var btnAddService: UIButton!

    class func instanceFromNib() -> UIView {
        return UINib(nibName: "ServiceAuthHeaderView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
    }

    @IBAction func onAddService(sender: AnyObject) {
        onAddServiceCallback?(sender: sender)
    }
}

class MyViewController: UIViewController {
    var myServiceAuthHeaderView: ServiceAuthHeaderView?

    // some initialization function
    func initViews() {
        myServiceAuthHeaderView?.onAddServiceCallback = { sender in
            // handling the callback
        }
    }
}

这两种方法都适用。第二个需要更少的代码(不需要创建额外的协议)

答案 1 :(得分:1)

除了@fiks建议的委托和回调之外,您还可以简单地使用添加目标。

第1步: 更改以下内容以返回ServiceAuthHeaderView而不是UIView,以便您可以访问其IBOutlet。我从ServiceAuthHeaderView将其重命名为ServiceAuthHeaderViewController,因为这是UIView的子类。

class func instanceFromNib() -> ServiceAuthHeaderView {
    return UINib(nibName: "ServiceAuthHeaderView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! ServiceAuthHeaderView
}

第2步:在子类UIViewController的父级中,在btnAddService

中添加viewDidLoad目标
class ServiceAuthViewController: UIViewController {

  override func viewDidLoad() {
      let headerView = ServiceAuthHeaderView.instanceFromNib()
      headerView.btnAddService.addTarget(self, action: #selector(ServiceAuthViewController.btnAddServicePressed(_:)), forControlEvents: .TouchUpInside)
  }
}

第3步:创建您在选择器中输入的目标操作,并在按下按钮时执行您需要的操作。

func btnAddServicePressed(button: UIButton) {
    print("Code for button pressed should be place here")
}