UITabBarController - 如何制作简单开关的动画?

发布于 2024-12-08 21:53:18 字数 3708 浏览 0 评论 0原文

我对这件事还很陌生。这个应用程序只是我的第二个。

我有一个 TabBarController,有两种在视图之间切换的方法:

方法 1:使用选项卡栏图标。我已经提供了必要的委托回调。它是这样的:

/***************************************************************\**
 \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;
}

效果很好。

方法 2:抓住滑动,并以这种方式触发转换,如下所示:

/***************************************************************\**
 \brief Gesture Callback -Swipes from the List View to the Map View
 *****************************************************************/
- (IBAction)swipeFromList:(UIGestureRecognizer *)sender
{
    [tabBarController setSelectedIndex:1];
}

这样做的问题是我无法让转换起作用。如果我将转换代码添加到滑动处理程序中,如下所示:

/***************************************************************\**
 \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];
}

它第一次工作,但在后续操作中出现蛇眼。

我确信我在这里犯了一些基本的、可笑的错误,并且正在寻找线索。

线索,有人吗?

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑饮青盏花 2024-12-15 21:53:18

哇。我解决了它,我不太清楚为什么,但它有效。

这就是我所做的:

首先,我将转换分解为标准方法:

/***************************************************************\**
 \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];
            }
        }
}

接下来,我在标签栏转换发生之前拦截它,并覆盖它,如下所示:

/***************************************************************\**
 \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;
}

然后,我将以下代码添加到滑动陷阱中:

/***************************************************************\**
 \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];
}

现在,这里的问题是,当我返回到我滑动的视图(不使用选项卡栏)时,我总是会崩溃。崩溃表明目标视图已被取消分配。

在检查了一些鸡内脏后,我决定我需要捂住鼻子,并保留之前的观点,就像这样:

    [[listSearchController view] retain];
    [self transitionBetweenThisView:[listSearchController view] andThisView:[mapSearchController view]];

可以。我用仪器检查过。没有泄漏。

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.

这个俗人 2024-12-15 21:53:18

此代码运行良好 **

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

                }];**

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

                }];**
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文