如何从另一个视图控制器设置按钮的动作

时间:2018-12-04 10:32:11

标签: ios swift

如何创建类似于UIAlertController的可重用视图控制器(我们称为“ reusableVC”)。 ReusableVC具有“确定”按钮,该按钮的作用取决于resuableVC的调用位置。我了解代表和NotificationCenter。只是想知道我们能否在创建reusableVC时传递“确定”按钮应该执行的操作,就像这样:

reusableVC.addAction(UIAlertAction(title: "", style: .default, handler: { (action) in
   // some code
}))

5 个答案:

答案 0 :(得分:2)

如果只需要一个OK按钮,则可以使用此解决方案,否则,您仍然会对这种模式感兴趣。

class ReusableVC{
    var onOKPressed: ( () -> () )?

    // Create all your other things and don't forget that you should call onOKPressed() whenever user pushed that OK button
}

class ViewController{

    func setupReusableVC(){

        let reusableVC = ReusableVC()
        reusableVC.onOKPressed = {
            print("ok pressed")
        }
    }
}

答案 1 :(得分:1)

动作处理程序只是一个闭包。您可以在任何地方声明它。


在可重用的视图控制器中添加属性

var customAction : ((UIAlertAction) -> Void)?

并将属性作为处理程序传递

reusableVC.addAction(UIAlertAction(title: "", style: .default, handler: customAction))

在源视图控制器中创建操作

let action : ((UIAlertAction) -> Void)? = { action in 
    // do something
}

并将其传递到perform(segue

答案 2 :(得分:0)

创建一个UIViewController扩展以包括警报功能

extension UIViewController{
    open func hideKeyBoardOnTap(){
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        self.view.addGestureRecognizer(tap)
    }

    @objc private func dismissKeyboard(){
        self.view.endEditing(true)
    }

    open func showAlertWithOK(_ title: String = "Alert!",message: String = "Please take appropriate action"){
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okButton = UIAlertAction(title: "Ok", style: .default, handler:{ (alertAction) in
            self.okAction()
        })
        alert.addAction(okButton)
        DispatchQueue.main.async {
            self.present(alert, animated: true, completion: nil)
        }
    }

    open func showAlertWithOkAndCancel(_ title: String = "Alert!",_ message: String = "Please take appropriate action", _ firstButtonTitle: String = "Ok", _ firstButtonStyle: UIAlertActionStyle = .default, _ secondButtonTitle: String = "Cancel",_ secondButtonStyle: UIAlertActionStyle = .cancel){
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okButton = UIAlertAction(title: firstButtonTitle, style: firstButtonStyle, handler:{ (alertAction) in
            self.okAction()
        })
        let cancelButton = UIAlertAction(title: secondButtonTitle, style: secondButtonStyle, handler: { (alertAction) in
            self.cancelAction()
        })
        alert.addAction(okButton)
        alert.addAction(cancelButton)
        self.present(alert, animated: true, completion: nil)
    }

    @objc private func okAction(){
        self.dismiss(animated: true, completion: nil)
    }

    @objc private func cancelAction(){
        self.dismiss(animated: true, completion: nil)
    }
}

使用方法

func didReceiveError(_ error: CFNetworkErrors) {
    var message = error.message
    self.showAlertWithOK("Error", message: message)
}

func didEndWebserviceCall() {
    self.showAlertWithOK(message: "didEndWebserviceCall")
}

优势:

  1. 您可以使用self(在这种情况下,这是您的视图控制器)来访问警报

  2. 代码可重用性

  3. 清洁代码。

答案 3 :(得分:0)

protocol TapEventDelegate: protocol {
func buttonTap()
}

class ClassWhereDoYouWantToCatchTheEvent: TapEventDelegate {
func buttonTap() {
print("caught!")
}
 }

class YourViewControllerClass {
weak var tapEventDelegate: TapEventDelegate?
reusableVC.addAction(UIAlertAction(title: "", style: .default, handler: { (action) in
   tapEventDelegate?.buttonTap()
}))
}

使用YourViewControllerClassClassWhereDoYouWantToCatchTheEvent绑定类,以在视图控制器初始化时使用:

classWhereDoYouWantToCatchTheEvent.tapEventHandler = yourViewControllerClass

答案 4 :(得分:0)

您可以创建自定义UIViewController类并传递addAction closure,然后可以在CustomAlertController上单击“确定”按钮时调用该闭包。

final class CustomAlertController: UIViewController {

    var actionHandler: (() -> Void)?

    lazy var okButton: UIButton = {
        let button = UIButton()
        button.backgroundColor = .black
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("OK", for: .normal)
        button.addTarget(self, action: #selector(CustomAlertController.didTapOkButton(_:)), for: .touchUpInside)
        button.layer.cornerRadius = 10
        return button
    }()

    override func loadView() {
        view = UIView()
        view.backgroundColor = .white
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        addActionButton()
    }

    private func addActionButton() {
        view.addSubview(okButton)
        NSLayoutConstraint.activate([
            okButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50),
            okButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50),
            okButton.heightAnchor.constraint(equalToConstant: 50),
            okButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 100)
        ])
    }

    public func addAction(title: String, handler: @escaping (() -> Void) {
        okButton.setTitle(title, for: .normal)
        actionHandler = handler
    }

    @objc func didTapOkButton(_ button: UIButton) {
        actionHandler?()
        dismiss(animated: true)
    }
}

然后,您可以在CustomAlertController类中展示ViewController,并添加如下所示的操作

class ViewController: UIViewController {

    override func loadView() {
        view = UIView()
        view.backgroundColor = .white
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let alertController = CustomAlertController()
        alertController.addAction(title: "OK", handler: { [unowned self] in
            self.view.backgroundColor = .blue
            print("OK button tapped")
        })
        present(alertController, animated: true)
    }
}