carlodurso
carlodurso

Reputation: 2894

setting Delegates on destination viewController

This is puzzling me.

The context

The original tutorial I'm following.

enter image description here

Where the segue is added to the Main View via a custom segue:

- (void) perform {
    
    MainViewController *source = (MainViewController *)self.sourceViewController;
    UIViewController *destination = (UIViewController *) self.destinationViewController;
    
    for(UIView *view in source.main.subviews){
        [view removeFromSuperview];
    }
    
    source.currentViewController = destination;
    destination.view.frame = CGRectMake(0, 0, source.main.frame.size.width, source.main.frame.size.height);
    [source.main addSubview:destination.view];
}

The TextField is connected as delegate in the child View Controller. All things being equal I get the app crashed without any message.


The workaround

In the Main View Controller, in -(void)prepareForSegue: I've added [segue.destinationViewController setDelegate:self]; in the meantime I've added a property in the child View Controller id<UITextFieldDelegate> delegate and modified the textfield delegate as self.delegate.

This works, but the trouble is that I've to set the delegated methods in Main View Controller which is not quite efficient as I have more View Controllers to add.


The Objective

How do I set each View Controller to be the delegate for itself without crashing?

Upvotes: 1

Views: 387

Answers (3)

Kyle Robson
Kyle Robson

Reputation: 3060

The immediate cause of your error is that the view controller that your views belong to is being deallocated. The fact that your views are on screen while their view controller is deallocated highlights a fundamental flaw in the approach of taking views off one view controller and adding them to another. View controller containment is the correct way to solve an issue like this.

Changing the currentViewController property to strong will fix the memory management issue you're seeing, but it's just a bandaid. Your currentViewController will still be missing rotation methods, appearance and disappearance methods, layout methods, and so forth. View controller containment ensures these methods get called for the view controller whose views are on screen.

Here is an altered version of your project that illustrates how to use view controller containment. I think that will be a better solution than manually removing and adding subviews of the view controllers themselves. See the Apple docs for more info on custom view controller containers.

Upvotes: 3

orkenstein
orkenstein

Reputation: 2858

At first, let's see crash report. Please, do the following:
1. Add Exception Breakpoint
2. Edit it as in the picture

enter image description here

Upvotes: 1

dmerlea
dmerlea

Reputation: 936

You should create a custom class for the destinationViewController wich will implement UITextFieldDelegate

@interface DestinationViewController <UITextFieldDelegate>

@end

And from storyboard add the class to UIViewController that has TextField enter image description here

And make the connections for elements and TextField delegate.

Implement delegate methods.

You will not need the implementation of prepareForSegue: anymore. You will have two different classes with different elements. Only if you need to pass something from source to destination then you use prepareForSegue:

Hope you'll understand

Upvotes: 1

Related Questions