使用动画同时隐藏UINavBar和UITabBar [英] Hide UINavBar and UITabBar at the same time with animation

查看:60
本文介绍了使用动画同时隐藏UINavBar和UITabBar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我将赏金授予了john,因为他在回答中付出了很多努力,并且无论如何都会得到帮助,但仍然没有可行的解决方案。我仍在寻找答案,如果有人知道如何做到这一点,将不胜感激。

Edit: I awarded the bounty to john since he put a lot of effort into his answer, and would get it anyways, but there's still no working solution. I am still looking for an answer, if someone knows how to do this it'd be greatly appreciated.

我想在我的应用中添加一个最大化按钮,隐藏导航和标签栏。导航栏和标签栏应平滑地滑入/滑出,并且内部/内容视图也应以与导航栏和标签栏相同的速率扩展和缩小。

I want to add a "maximize" button to my app that hides the navigation and tab bar. The navbar and tabbar should slide in/out smoothly, and the inner/content view should also expand and shrink at the same rate as the navbar and tabbar.

我使用了 [self.navigationController setNavigationBarHidden:是/否动画:是]; 对于导航栏,发现此线程如何隐藏uitabbarcontroller 以隐藏标签栏。

I used [self.navigationController setNavigationBarHidden: YES/NO animated: YES]; for the navbar and found this thread How to hide uitabbarcontroller for hiding the tabbar.

UITabBar类扩展:

UITabBar class extension:

- (void) setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
    CGRect screenRect = [[UIScreen mainScreen] bounds];

    float screenHeight = screenRect.size.height;
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
        screenHeight = screenRect.size.width;
    }
    if (!hidden) {
        screenHeight -= self.tabBar.frame.size.height;
    }
    [UIView animateWithDuration: (animated ? UINavigationControllerHideShowBarDuration : 0) animations: ^{
        for (UIView* each in self.view.subviews) {
            if (each == self.tabBar) {
                [each setFrame: CGRectMake(each.frame.origin.x, screenHeight, each.frame.size.width, each.frame.size.height)];
            } else {
                [each setFrame: CGRectMake(each.frame.origin.x, each.frame.origin.y, each.frame.size.width, screenHeight)];
            }
        }
    } completion: ^(BOOL finished) {
        NSLog(@"Animation finished %d", finished);
    }];
}

问题是当我同时使用两者时(隐藏/显示导航栏和标签栏),这不干净。如果导航栏位于第一位,则锚定在底部的所有内容都会跳转(请参见下面的示例),如果导航栏位于第一位,则位于顶部的内容就会跳转。

The problem is when I use the two at the same time (hiding/showing the nav and tab bar), it's not clean. If the navbar comes first, anything anchored to the bottom jumps (see example below), and if the tabbar comes first, the top jumps.

示例:我将UIButton放在位置在右下角并设置其自动调整大小蒙版

Example: I position the UIButton in the bottom right and set its autoresizing mask

resizeButton.frame = CGRectMake(self.view.bounds.size.width - 50, self.view.bounds.size.height - 100, 32, 32); // hardcoded just for testing purposes
resizeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;

但是,当导航栏和标签栏最小化时,UIButton会在两个状态之间跳转(不会沿标签栏)。但是,如果我将其更改为附在右上角,则它可以与导航栏完美滑动。

But when the navbar and tabbar are minimized the UIButton jumps between the two states (doesn't slide along with the tab bar). However, if I change it to attach to the top right, it slides perfectly with the nav bar.

有人知道如何解决这个问题吗?

Does anyone know how to solve this?

编辑
这是我到目前为止拥有的壁橱和最优雅的解决方案(只是试图获得一个可行的概念):

Edit: This is the closet and most elegant solution I have so far (just trying to get a working concept):

[UIView animateWithDuration: UINavigationControllerHideShowBarDuration animations: ^{
    if (self.isMaximized) {
        self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height + 49 - 20);
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    } else {
        self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height - 20);
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
} completion: ^(BOOL finished) {
    NSLog(@"Frame done: %@", NSStringFromCGRect(self.view.frame));
    return;
}];

最大化:


  • 同时向上滑动导航栏和向下滑动标签栏

  • 内部/内容视图的顶部向上滑动,而该视图的底部向下滑动

在最小化时:


  • 滑动导航栏

  • 内部/内容视图的顶部适当地向下滑动,但是底部/底部跳到最终值,留下空白,然后将其覆盖通过滑动标签栏

如果我重新排列了最小化动画的顺序(因此首先将导航栏animatino称为),则顶部在内部/内容视图中跳转

If I rearange the order of the minimizing-animations (so the navbar animatino is called first), then the top in the inner/content view jumps

推荐答案

我使用的解决方案应消除您看到的跳转问题。

the solution i use should eliminate the jump problem you see.

此解决方案源自卡洛斯·奥利瓦(Carlos Oliva)的github页面,尽管该代码的版权是保留所有权利,但我写了他的信,他提供了使用许可。

this solution is derived from an Objective-C category found Carlos Oliva's github page, and while the copyright in that code is "all rights reserved", i wrote him and he provided permission for use.

我的类别代码与他的代码略有不同。同样,在类别代码下面找到我在我的应用中使用的调用代码。

my category code varies only slightly from his code. also, find below the category code the invocation code that i use in my app.

来自UITabBarController + HideTabBar.m

from UITabBarController+HideTabBar.m

// the self.view.frame.size.height can't be used directly in isTabBarHidden or
// in setTabBarHidden:animated: because the value may be the rect with a transform.
//
// further, an attempt to use CGSizeApplyAffineTransform() doesn't work because the
// value can produce a negative height.
// cf. http://lists.apple.com/archives/quartz-dev/2007/Aug/msg00047.html
//
// the crux is that CGRects are normalized, CGSizes are not.

- (BOOL)isTabBarHidden {
    CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
    CGRect tabBarFrame = self.tabBar.frame;
    return tabBarFrame.origin.y >= viewFrame.size.height;
}


- (void)setTabBarHidden:(BOOL)hidden {
    [self setTabBarHidden:hidden animated:NO];
}


- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
    BOOL isHidden = self.tabBarHidden;
    if (hidden == isHidden)
        return;
    UIView* transitionView = [self.view.subviews objectAtIndex:0];

    if (!transitionView)
    {
#if DEBUG
    NSLog(@"could not get the container view!");
#endif
        return;
    }

    CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
    CGRect tabBarFrame = self.tabBar.frame;
    CGRect containerFrame = transitionView.frame;
    tabBarFrame.origin.y = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
    containerFrame.size.height = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
    [UIView animateWithDuration:kAnimationDuration 
                     animations:^{
                         self.tabBar.frame = tabBarFrame;
                         transitionView.frame = containerFrame;
                     }
     ];
}

来自我的ScrollableDetailImageViewController.m

from my ScrollableDetailImageViewController.m

- (void)setBarsHidden:(BOOL)hidden animated:(BOOL)animated
{
    [self setTabBarHidden:hidden animated:animated];
    [self setStatusBarHidden:hidden animated:animated];

    // must be performed after hiding/showing of statusBar
    [self.navigationController setNavigationBarHidden:hidden animated:animated];
}

- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated
{
    id parent = self.navigationController.parentViewController;
    if ([parent respondsToSelector:@selector(isTabBarHidden)]
        && hidden != [parent isTabBarHidden]
        && [parent respondsToSelector:@selector(setTabBarHidden:animated:)])
        [parent setTabBarHidden:hidden animated:animated];
}

这篇关于使用动画同时隐藏UINavBar和UITabBar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆