简体   繁体   中英

UITabBarController -How Can I Animate Simple Switches?

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;
                    }

                }];**

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM