Delegates in swift?

前端 未结 12 1321
天命终不由人
天命终不由人 2020-11-22 03:27

How does one go about making a delegate, i.e. NSUserNotificationCenterDelegate in swift?

相关标签:
12条回答
  • 2020-11-22 04:15

    I got few corrections to post of @MakeAppPie

    First at all when you are creating delegate protocol it should conform to Class protocol. Like in example below.

    protocol ProtocolDelegate: class {
        func myMethod(controller:ViewController, text:String)
    }
    

    Second, your delegate should be weak to avoid retain cycle.

    class ViewController: UIViewController {
        weak var delegate: ProtocolDelegate?
    }
    

    Last, you're safe because your protocol is an optional value. That means its "nil" message will be not send to this property. It's similar to conditional statement with respondToselector in objC but here you have everything in one line:

    if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
        [self.delegate myMethod:self text:@"you Text"];
    }
    

    Above you have an obj-C example and below you have Swift example of how it looks.

    delegate?.myMethod(self, text:"your Text")
    
    0 讨论(0)
  • 2020-11-22 04:16

    Delegates are a design pattern that allows one object to send messages to another object when a specific event happens. Imagine an object A calls an object B to perform an action. Once the action is complete, object A should know that B has completed the task and take necessary action, this can be achieved with the help of delegates! Here is a tutorial implementing delegates step by step in swift 3

    Tutorial Link

    0 讨论(0)
  • 2020-11-22 04:21

    Here's a little help on delegates between two view controllers:

    Step 1: Make a protocol in the UIViewController that you will be removing/will be sending the data.

    protocol FooTwoViewControllerDelegate:class {
        func myVCDidFinish(_ controller: FooTwoViewController, text: String)
    }
    

    Step2: Declare the delegate in the sending class (i.e. UIViewcontroller)

    class FooTwoViewController: UIViewController {
        weak var delegate: FooTwoViewControllerDelegate?
        [snip...]
    }
    

    Step3: Use the delegate in a class method to send the data to the receiving method, which is any method that adopts the protocol.

    @IBAction func saveColor(_ sender: UIBarButtonItem) {
            delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
    }
    

    Step 4: Adopt the protocol in the receiving class

    class ViewController: UIViewController, FooTwoViewControllerDelegate {
    

    Step 5: Implement the delegate method

    func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
        colorLabel.text = "The Color is " +  text
        controller.navigationController.popViewController(animated: true)
    }
    

    Step 6: Set the delegate in the prepareForSegue:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "mySegue" {
            let vc = segue.destination as! FooTwoViewController
            vc.colorString = colorLabel.text
            vc.delegate = self
        }
    }
    

    And that should work. This is of course just code fragments, but should give you the idea. For a long explanation of this code you can go over to my blog entry here:

    segues and delegates

    If you are interested in what's going on under the hood with a delegate I did write on that here:

    under the hood with delegates

    0 讨论(0)
  • 2020-11-22 04:22

    Very easy step by step (100% working and tested)

    step1: Create method on first view controller

     func updateProcessStatus(isCompleted : Bool){
        if isCompleted{
            self.labelStatus.text = "Process is completed"
        }else{
            self.labelStatus.text = "Process is in progress"
        }
    }
    

    step2: Set delegate while push to second view controller

    @IBAction func buttonAction(_ sender: Any) {
    
        let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
        secondViewController.delegate = self
        self.navigationController?.pushViewController(secondViewController, animated: true)
    }
    

    step3: set delegate like

    class ViewController: UIViewController,ProcessStatusDelegate {

    step4: Create protocol

    protocol ProcessStatusDelegate:NSObjectProtocol{
    func updateProcessStatus(isCompleted : Bool)
    }
    

    step5: take a variable

    var delegate:ProcessStatusDelegate?
    

    step6: While go back to previous view controller call delegate method so first view controller notify with data

    @IBAction func buttonActionBack(_ sender: Any) {
        delegate?.updateProcessStatus(isCompleted: true)
        self.navigationController?.popViewController(animated: true)
    }
    
    @IBAction func buttonProgress(_ sender: Any) {
        delegate?.updateProcessStatus(isCompleted: false)
        self.navigationController?.popViewController(animated: true)
    
    }
    
    0 讨论(0)
  • 2020-11-22 04:24

    Delegates always confused me until I realized that a delegate is just a class that does some work for another class. It's like having someone else there to do all the dirty work for you that you don't want to do yourself.

    I wrote a little story to illustrate this. Read it in a Playground if you like.

    Once upon a time...

    // MARK: Background to the story
    
    // A protocol is like a list of rules that need to be followed.
    protocol OlderSiblingDelegate: class {
        // The following command (ie, method) must be obeyed by any 
        // underling (ie, delegate) of the older sibling.
        func getYourNiceOlderSiblingAGlassOfWater()
    }
    
    // MARK: Characters in the story
    
    class BossyBigBrother {
        
        // I can make whichever little sibling is around at 
        // the time be my delegate (ie, slave)
        weak var delegate: OlderSiblingDelegate?
        
        func tellSomebodyToGetMeSomeWater() {
            // The delegate is optional because even though 
            // I'm thirsty, there might not be anyone nearby 
            // that I can boss around.
            delegate?.getYourNiceOlderSiblingAGlassOfWater()
        }
    }
    
    // Poor little sisters have to follow (or at least acknowledge) 
    // their older sibling's rules (ie, protocol)
    class PoorLittleSister: OlderSiblingDelegate {
    
        func getYourNiceOlderSiblingAGlassOfWater() {
            // Little sis follows the letter of the law (ie, protocol),
            // but no one said exactly how she had to respond.
            print("Go get it yourself!")
        }
    }
    
    // MARK: The Story
    
    // Big bro is laying on the couch watching basketball on TV.
    let bigBro = BossyBigBrother()
    
    // He has a little sister named Sally.
    let sally = PoorLittleSister()
    
    // Sally walks into the room. How convenient! Now big bro 
    // has someone there to boss around.
    bigBro.delegate = sally
    
    // So he tells her to get him some water.
    bigBro.tellSomebodyToGetMeSomeWater()
    
    // Unfortunately no one lived happily ever after...
    
    // The end.
    

    In review, there are three key parts to making and using the delegate pattern.

    1. the protocol that defines what the worker needs to do
    2. the boss class that has a delegate variable, which it uses to tell the worker class what to do
    3. the worker class that adopts the protocol and does what is required

    Real life

    In comparison to our Bossy Big Brother story above, delegates are often used for the following practical applications:

    1. Communication: one class needs to send some information to another class.
      • Code example 1: sending data from one view controller to another
      • Code example 2: sending text input from a custom keyboard to a text field
    2. Customization: one class wants to allow another class to customize it.

    The great part is that these classes don't need to know anything about each other beforehand except that the delegate class conforms to the required protocol.

    I highly recommend reading the following two articles. They helped me understand delegates even better than the documentation did.

    • What is Delegation? – A Swift Developer’s Guide
    • How Delegation Works – A Swift Developer’s Guide

    One more note

    Delegates that reference other classes that they do not own should use the weak keyword to avoid strong reference cycles. See this answer for more details.

    0 讨论(0)
  • 2020-11-22 04:24

    Here's a gist I put together. I was wondering the same and this helped improve my understanding. Open this up in an Xcode Playground to see what's going on.

    protocol YelpRequestDelegate {
        func getYelpData() -> AnyObject
        func processYelpData(data: NSData) -> NSData
    }
    
    class YelpAPI {
        var delegate: YelpRequestDelegate?
    
        func getData() {
            println("data being retrieved...")
            let data: AnyObject? = delegate?.getYelpData()
        }
    
        func processYelpData(data: NSData) {
            println("data being processed...")
            let data = delegate?.processYelpData(data)
        }
    }
    
    class Controller: YelpRequestDelegate {
        init() {
            var yelpAPI = YelpAPI()
            yelpAPI.delegate = self
            yelpAPI.getData()
        }
        func getYelpData() -> AnyObject {
            println("getYelpData called")
            return NSData()
        }
        func processYelpData(data: NSData) -> NSData {
            println("processYelpData called")
            return NSData()
        }
    }
    
    var controller = Controller()
    
    0 讨论(0)
提交回复
热议问题