emleeh
emleeh

Reputation: 116

Setting a delegate between a view controller and a non presented view controller

I have a view controller, ViewControllerA.

I have set up a modal, ViewControllerB, that transitions to another view controller, ViewControllerC and then is dismissed to reveal ViewControllerA.

How can I set up a delegate method between ViewControllerA and ViewControllerC when I'm not pushing ViewControllerC from ViewControllerA so I can't explicitly set it's delegate in the ViewControllerA file?

Thank you.

Upvotes: 0

Views: 367

Answers (1)

Nimble
Nimble

Reputation: 1017

You can use closures to deliver a callback when something is finished. Sounds like ViewControllerA shouldn't know anything about ViewControllerC. ViewControllerA just opens ViewControllerB and then needs to receive a feedback. Here's how it looks:

class ViewControllerA: UIViewController {
    let viewControllerB = ViewControllerB()
    func showViewControllerB() {
        viewControllerB.onFinish = {
            // work is done in ViewControllerB and C
        }
        presentViewController(viewControllerB, animated: true, completion: nil)
    }
}

Here's how ViewControllerB and ViewControllerC look like:

class ViewControllerB: UIViewController {
    var onFinish: (() -> ())?
    let viewControllerC = ViewControllerC()

    override func viewDidLoad() {
        super.viewDidLoad()
        viewControllerC.onFinish = { [weak self] in
            self?.onFinish?()
        }
    }

    func showViewControllerC() {
        presentViewController(viewControllerC, animated: true, completion: nil)
    }
}

class ViewControllerC: UIViewController {
    var onFinish:(() -> ())?
    func didFinishDoSomething() {
        onFinish?()
    }
}

The code above just shows a concept how you can reuse closures for callbacks between view controllers.


The concept is the same if you use Objective-C. In this case blocks are used:

@interface ViewControllerA: UIViewController
@property (strong) ViewControllerB *viewControllerB;
@end

@implementation ViewControllerA

- (void)viewDidLoad {
    [super viewDidLoad];
    self.viewControllerB.onFinish = ^{
        // work is done in both VC B and VC C
    };
}

- (void)showViewControllerB {
    [self presentViewController:self.viewControllerB animated:YES completion:nil];
}

@end

Where onFinish is a property of ViewControllerB @property (copy) void (^onFinish)();

Upvotes: 1

Related Questions