简体   繁体   中英

iOS (Swift): Protocol for UIViewController that adds a new object

I have a view controller that is responsible for adding a new object, say a new contact. This view controller ( AddContactViewController ) has the following UIBarButtonItem on a UINavigationBar , which is starts of disabled until enough information is provided to enable it. Then when this button is pressed a method ( doneButtonPressed ) is called.

The layout is as follows:

class AddContactViewController: UIViewController {

    @IBOutlet weak var doneButton: UIBarButtonItem! {
        didSet {
            doneButton.isEnabled = false
            doneButton.target = self
            doneButton.action = #selector(self.doneButtonPressed)
        }
    }

     @objc fileprivate func doneButtonPressed() {
         // do some stuff ...
         self.dismiss(animated: false, completion: nil)
     }

}

As this is quite a common thing to have and there's a lot of boiler plate code, I've been working on a protocol AddingHandler but haven't quite worked out how to have UIBarButtonItem as a weak variable which hooks up to a storboard or if this is even the right way to go.

protocol AddingHandler {
    var doneButton: UIBarButtonItem? { get set }
    func doneButtonPressed()
}

extension protocol where Self: UIViewController {
    func configureDoneButton() {
        doneButton.isEnabled = false
        doneButton.target = self
        doneButton.action = #selector(self.doneButtonPressed)        
    }
}

Any help or comments in making this work would be much appreciated.

The problem How is best to add a weak UIButton to a protocol which can then be hooked up in a story board where UIViewController implements it? As there is a lot of repetitive code here should I wish to have another AddSomethingViewController I was wondering if there was a neater way of only writing this once (in a protocol with an extension) then calling the protocol in any view controller that is adding something new ...

You can simply configure the doneButton in viewDidLoad()

override func viewDidLoad()
{
    super.viewDidLoad()
    doneButton.isEnabled = false
    doneButton.target = self
    doneButton.action = #selector(self.doneButtonPressed)
}

Edit 1:

@objc protocol AddingHandler
{
    var doneButton: UIBarButtonItem? { get }
    @objc func doneButtonPressed()
}

extension AddingHandler where Self: UIViewController
{
    func configureDoneButton()
    {
        doneButton?.isEnabled = false
        doneButton?.target = self
        doneButton?.action = #selector(doneButtonPressed)
    }
}

class AddContactViewController: UIViewController, AddingHandler
{
    @IBOutlet weak var doneButton: UIBarButtonItem!

    override func viewDidLoad()
    {
        super.viewDidLoad()
        configureDoneButton()
    }

    func doneButtonPressed()
    {
        // do some stuff ...
        self.dismiss(animated: false, completion: nil)
    }
}

I've used ObjC runtime to resolve the issue. Try implementing it at your end and check if it works for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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