Reputation: 4173
I am working on view A (createExerciseViewController) that adds view B (createRoutinePopupViewController) after clicking a UIButton.
This part works fine and the view is added fine.
Then inside view B (createRoutinePopupViewController) I have another UIButton. When I click this UIButton then the app crashes and all i get as an error is (lldb)
and the NSLog is not executed.
but then sometimes and only sometimes it all gets executed fine after several crashes...
I am quite new to the iOS dev world and I have no idea what I could be doing wrong.
All UIButton method are strong
Does anyone know why this could be happening?
I think the issue could be in how i am inserting the subview and handling the whole subview??
A ---- createExerciseViewController.m
#import "createExerciseViewController.h"
#import "createExercisePopupViewController.h"
#import "createRoutinePopupViewController.h"
// ....more code
- (IBAction)createRoutine:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
[self.view addSubview:[[storyboard instantiateViewControllerWithIdentifier:@"createRoutinePopupView"] view]];
}
this is UIViewController
B ---- createRoutinePopupViewController.m
#import "createRoutinePopupViewController.h"
#import "createExerciseViewController.h"
#import "User.h"
#import "Routine.h"
- (IBAction)createRoutine:(UIButton *)sender {
NSLog(@"Please dont crash");
}
Upvotes: 1
Views: 946
Reputation: 1328
You shouldn't be creating view controllers just to add their views to another view controller's view willy-nilly. You need to tell the system that you're moving views from one controller to another, so that it can do its housekeeping. If you don't do this, one view controller ends up owning a view that's being presented by another view controller, so events and touches etc get confused. This may be what's causing the crash.
iOS now provides a 'container view controller' mechanism to manage this situation, whereby you tell the system that you're moving a view from one controller to another.
From Apple's doc:
The goal of implementing a container is to be able to add another view controller’s view (and associated view hierarchy) as a subtree in your container’s view hierarchy. The child remains responsible for its own view hierarchy, save for where the container decides to place it onscreen. When you add the child’s view, you need to ensure that events continue to be distributed to both view controllers. You do this by explicitly associating the new view controller as a child of the container.
In practice, it's simpler than it sounds. Try something like this in createExerciseViewController.m:
- (IBAction)createRoutine:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
CreateRoutinePopupViewController* popupController = [storyboard instantiateViewControllerWithIdentifier:@"createRoutinePopupView"];
//Tell the operating system the CreateRoutine view controller
//is becoming a child:
[self addChildViewController:popupController];
//add the target frame to self's view:
[self.view addSubview:popupController.view];
//Tell the operating system the view controller has moved:
[popupController didMoveToParentViewController:self];
}
Upvotes: 7
Reputation: 1605
Try this:
CreateRoutinePopupViewController *popUp = [[storyboard instantiateViewControllerWithIdentifier:@"createRoutinePopupView"];
[self presentModalViewController:popUp Animated:YES];
Upvotes: -1