我如何"合法地"淡出应用程序中的导航栏?

Dou*_*ith 16 objective-c uinavigationbar uiview uinavigationcontroller ios

似乎删除动画导航栏的唯一方法是通过它向上滑动.我想让它褪色,就像在Photos.app中一样.

改变alpha是最容易的,但Apple的指导原则是:

在iOS v5.0之前,当与导航控制器结合使用时,只能对导航栏进行少量直接自定义.具体来说,可以修改barStyle,tintColor和半透明属性,但是您不能直接直接更改UIView级属性,例如框架,边界,alpha或隐藏属性.

该语言有点奇怪,因为它在iOS 5之前表示,但它声明你不允许直接更改alpha值,并且它从未声明你现在被允许.

我不希望我的应用被拒绝.

我如何像状态栏一样淡出导航栏?

Tom*_*ift 12

这是一个有趣的解决方案.

它应该非常简单:用于UIView transitionWithView在导航栏的隐藏和非隐藏状态之间执行交叉淡入淡出,由公共API设置setNavigationBarHidden:animated:.事实上,这适用于"淡出"导航栏,但是将其淡入还有一个问题.问题在于,除非您指定,否则导航栏将滑动到位,无论UIView +transitionWithView:动画属性(例如frame)没有动画UIViewAnimationOptionAllowAnimatedContent.

对我来说,这表示内部UINavigationController重新定位UINavigationBar动画块内部,无论是否在调用中指定了动画setNavigationBarHidden:animated:.当这个动画块的持续时间可能是设置为"0" animate:设置为NO.

解决方案是在交叉淡入淡出过渡之前将导航栏设置为可见(无动画).这可确保导航栏在正确位置开始交叉淡入淡出,并且交叉淡入淡出仅显示新的非隐藏状态.

我的示例项目是标准的单视图应用程序.在故事板上是一个UINavigationController,这是切入点.我将此控制器的条形样式设置UINavigationBar为黑色半透明(类似于照片应用程序).导航控制器rootViewController是一个简单UIViewControllerUIImageView填充整个边界(也像照片应用程序).我UITapGestureRecognizer在视图中添加了一个以在视图控制器中调用以下代码:

- (IBAction) onShowHideNavbar: (id) sender
{
    BOOL hide = !self.navigationController.navigationBarHidden;

    if ( !hide)
    {
        [self.navigationController setNavigationBarHidden: hide animated: NO];
    }

    [UIView transitionWithView: self.navigationController.view
                      duration: 1
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^{

                        [self.navigationController setNavigationBarHidden: hide animated: NO];
                    }
                    completion: nil ];
}
Run Code Online (Sandbox Code Playgroud)

所有这些说,我认为你不会因为UINavigationBar直接搞乱隐藏或alpha属性而遇到任何麻烦(Apple Rejection).文档警告不要触摸它们,因为它们由UINavigationController管理并且更改它们可能会产生看不见的后果.但在我的意见中,他们是公共API,因此使用它们不应该被拒绝.


Lom*_*baX 6

您无法合法地为UINavigationController的导航栏的属性设置动画.
但是,您可以显示带有隐藏导航栏的导航控制器(根据您的喜好将其隐藏或仅隐藏在特定的视图控制器上),并将其替换为您的"特殊"实例UINavigationBar;-)

我附上了一个示例项目(我使用Xcode模板更快地创建它):FakeNavBar

看看viewDidLoad方法DetailViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self configureView];

    self.fakeBar = [[UINavigationBar alloc]initWithFrame:self.navigationController.navigationBar.bounds];


    UIBarButtonItem *back = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(back)];



    UINavigationItem *backItem = [[UINavigationItem alloc]initWithTitle:@"Back"];
    backItem.leftBarButtonItem = back;
    [self.fakeBar pushNavigationItem:backItem animated:YES];

    [self.view addSubview:self.fakeBar];

}
Run Code Online (Sandbox Code Playgroud)

这是YouTube上最终产品的视频.