I'm still fairly new at this stuff. This app is only my second.
I have a TabBarController, and there are two ways of switching between the views:
METHOD 1: Use the Tab Bar Icons. I've provided the requisite delegate callback. It is something like this:
/***************************************************************\**
\brief This animates the view transitions, and also sets up anything
that needs doing between views.
*****************************************************************/
- (BOOL)tabBarController:(UITabBarController *)inTabBarController
shouldSelectViewController:(UIViewController *)inViewController
{
BOOL ret = NO;
// Need to have all of these to work.
if ( inTabBarController && [inTabBarController view] && inViewController && [inViewController view] )
{
UIView *srcView = [[inTabBarController selectedViewController] view];
UIView *dstView = [inViewController view];
if ( srcView != dstView )
{
if ( srcView == [prefsController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionCurlDown
completion:nil];
}
else if ( dstView == [prefsController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
开发者_运维百科 options:UIViewAnimationOptionTransitionCurlUp
completion:nil];
}
else if ( srcView == [listSearchController view] && dstView == [mapSearchController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];
}
else if ( dstView == [listSearchController view] && srcView == [mapSearchController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
ret = YES;
}
}
return ret;
}
Works great.
METHOD 2: Grab swipes, and trigger the transitions that way, like so:
/***************************************************************\**
\brief Gesture Callback -Swipes from the List View to the Map View
*****************************************************************/
- (IBAction)swipeFromList:(UIGestureRecognizer *)sender
{
[tabBarController setSelectedIndex:1];
}
The problem with this, is that I can't get the transition to work. If I add the transition code to the swipe handler, like so:
/***************************************************************\**
\brief Gesture Callback -Swipes from the List View to the Map View
*****************************************************************/
- (IBAction)swipeFromList:(UIGestureRecognizer *)sender
{
[UIView transitionFromView:[listSearchController view]
toView:[mapSearchController view]
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];
[tabBarController setSelectedIndex:1];
}
It works the first time, but comes up snake eyes on subsequent goes.
I'm sure that I am making some basic, chuckleheaded error here, and am searching for clues.
Clues, anyone?
Thanks!
Wow. I solved it, and I am not exactly sure why, but it works.
Here's what I did:
First, I factored the transitions into a standard method:
/***************************************************************\**
\brief Manages the transition from one view to another. Just like
it says on the tin.
*****************************************************************/
- (void)transitionBetweenThisView:(UIView *)srcView
andThisView:(UIView *)dstView
{
if ( srcView != dstView )
{
if ( srcView == [prefsController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionCurlDown
completion:nil];
}
else if ( dstView == [prefsController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionCurlUp
completion:nil];
}
else if ( srcView == [listSearchController view] && dstView == [mapSearchController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];
}
else if ( dstView == [listSearchController view] && srcView == [mapSearchController view] )
{
[UIView transitionFromView:srcView
toView:dstView
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
}
}
Next, I intercept the tab bar transition before it happens, and override it, like so:
/***************************************************************\**
\brief This animates the view transitions, and also sets up anything
that needs doing between views. It stops the tab bar controller
from managing the transition, and does it manually.
\returns a BOOL. Always NO.
*****************************************************************/
- (BOOL)tabBarController:(UITabBarController *)inTabBarController
shouldSelectViewController:(UIViewController *)inViewController
{
[self transitionBetweenThisView:[[inTabBarController selectedViewController] view] andThisView:[inViewController view]];
int index = [[inTabBarController viewControllers] indexOfObject:inViewController];
[inTabBarController setSelectedIndex:index];
return NO;
}
Then, I added the following code to the swipe traps:
/***************************************************************\**
\brief Gesture Callback -Swipes from the List View to the Map View
*****************************************************************/
- (IBAction)swipeFromList:(UIGestureRecognizer *)sender
{
[self transitionBetweenThisView:[listSearchController view] andThisView:[mapSearchController view]];
[tabBarController setSelectedIndex:1];
}
Now, the problem here, was that I always got a crash when returning to a view that I had swiped from (not using the tab bar). The crash said that the destination view had been deallocated.
After checking some chicken entrails, I decided that I needed to hold my nose, and retain the previous view, like so:
[[listSearchController view] retain];
[self transitionBetweenThisView:[listSearchController view] andThisView:[mapSearchController view]];
That works. I checked it with Instruments. No leaks.
This code is working fine **
int controllerIndex = 2;
UIView * fromView = self.tabBarController .selectedViewController.view;
UIView * toView = [[self.tabBarController.viewControllers objectAtIndex:controllerIndex] view];
// Transition using a page curl.
[UIView transitionFromView:fromView toView:toView duration:0.5
options:(controllerIndex > self.tabBarController.selectedIndex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
completion:^(BOOL finished) {
if (finished) {
self.tabBarController.selectedIndex = controllerIndex;
}
}];**
精彩评论