thank you for your time, (As a side note, this question pertains mostly to iOS 4.2.3, I am aware some of these issues could be resolved with moving the code base to iOS 5, however we would like to release this app for phones running iOS 4 as well.)
I have a "MasterViewController" that is in charge of calling and dismising other UIVIewControllers.
First we trigger a new one:
In MasterViewController.m
-(IBAction)triggerPrime:(id)sender {
[self clearHomeScreen];
NSUInteger randomNumber = arc4random() % 2;
if (randomNumber == 0) {
self.flashTextViewIsDisplayed = NO;
ThinkOfViewController *thinkVC = [[ThinkOfViewController alloc] initWithNibName:@"ThinkOfViewController" bundle:nil];
self.thinkOfViewController = thinkVC;
[thinkVC release];
self.picturePrimeViewIsDisplayed = YES;
[self.view addSubview:self.thinkOfViewController.view];
}
else if (randomNumber == 1) {
self.picturePrimeViewIsDisplayed = NO;
FlashTextPrimeViewController *flashVC = [[FlashTextPrimeViewController alloc] initWithNibName:@"FlashTextPrimeViewController" bundle:nil];
self.flashTextPrimeViewController = flashVC;
[flashVC release];
self.flashTextViewIsDisplayed = YES;
[self.view addSubview:self.flashTextPrimeViewController.view];
}
Let's say that our randomNumber is 0, and it adds the ThinkOfViewController to the subview, (This is a very basic screen, it essentially displays some text with some assets animating:
In ThinkOfViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.thinkOf.alpha = 0.0;
self.dot1.alpha = 0.0;
self.dot2.alpha = 0.0;
self.dot3.alpha = 0.0;
self.background.alpha = 0.0;
[self animateViews];
}
-(void)animateViews {
[UIView animateWithDuration:0.25 animations:^ {
self.background.alpha = 1.0;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.75 delay:0.00 options:UIViewAnimationCurveEaseIn animations:^ {
self.thinkOf.alpha = 1.0;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.20 delay:0.60 options:UIViewAnimationCurveEaseIn animations:^ {
self.dot1.alpha = 1.0;
}completion:^(BOOL finsihed) {
[UIView animateWithDuration:0.20 delay:0.60 options:UIViewAnimationCurveEaseIn animations:^ {
self.dot2.alpha = 1.0;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.20 delay:0.60 options:UIViewAnimationCurveEaseIn animations:^ {
self.dot3.alpha = 1.0;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.50 delay:0.60 options:UIViewAnimationCurveEaseInOut animations:^{
self.view.alpha = 0.0;
}completion:^(BOOL finished) {
NSLog(@"all animations done");
[[NSNotificationCenter defaultCenter] postNotificationName:@"removeThinkOfView" object:nil];
}];
}];
}];
}];
}];
}];
}
As you can see, once the animation sequence is finished, I post a notification to NSNotificationCenter (which resides in the MasterViewController) to remove this viewController.
In MasterViewController.m
-(void)removeThinkOfView {
[self.thinkOfViewController.view removeFromSuperview];
[self showPicturePrime];
}
-(void)showPicturePrime {
if (self.picturePrimeViewController == nil) {
PicturePrimeViewController *pVC = [[PicturePrimeViewController alloc] initWithNibName:@"PicturePrimeViewController" bundle:nil];
self.picturePrimeViewController = pVC;
[pVC release];
[self.view addSubview:self.picturePrimeViewController.view];
}
else {
PicturePrimeViewController *pVC = [[PicturePrimeViewController alloc] initWithNibName:@"PicturePrimeViewController" bundle:nil];
self.picturePrimeViewController = pVC;
[pVC release];
[self.view addSubview:self.picturePrimeViewController.view];
}
}
Now a picturePrimeViewController is loaded and added to the subview, everything loads and displays fine. Now, to get a new prime, you simple swipe for a new one.
In picturePrimeViewController.m
-(void)handleSwipeFromRight:(UISwipeGestureRecognizer *)gestureRecognizer {
if (!transitioning) {
[self performTransition];
}
}
-(void)performTransition {
CATransition *transition = [CATransition animation];
transition.duration = 1.0;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
transitioning = YES;
transition.delegate = self;
[self.view.layer addAnimation:transition forKey:nil];
[UIView animateWithDuration:0.5 animations:^ {
self.view.alpha = 0.0;
}completion:^(BOOL finished) {
NSLog(@"Transition Animation Complete");
}];
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
transitioning = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:@"nextPrime" object:nil];
}
Now in the animationDidStop: Method, i again post another notification to the NSNotificationCenter back to the MasterViewController to signal another prime.
In MasterViewController.m
-(void)nextPrime {
if (self.picturePrimeViewIsDisplayed) {
[self.picturePrimeViewController.view removeFromSuperview];
self.picturePrimeViewController = nil;
[self showAPrime];
}
if (self.flashTextViewIsDisplayed) {
[self.flashTextPrimeViewController.view removeFromSuperview];
self.flashTextPrimeViewController = nil;
[self showAPrime];
}
}
However! Upon swiping the right, the view animates properly but then I get a bad access crash when the ThinkOfViewController is attempting to dealloc it's UIViews. So for some reason, it is taking that the ThinkOfViewController a long time to dealloc, when I assumed when I called [self.thinkOfViewController removeFromSuperview]
, it should of been removed immeditately.
(Side note, the textFlashViewController has no problems, the only problems are comming with this ThinkOfViewController).
Is this paradigm I set up a bad implmentation of dealing with UiViewController's comming in and out? I have read that delegation can help in this instance, I'm just not sure how that works.
If any of you have any ideas, I would be so grateful, as I have mined through forums and documentations and cannot see a solution to my rather custom implmentation of dealing with these views.