【问题标题】:Prevent the animation when clicking "Back" button in a navigation bar?单击导航栏中的“返回”按钮时阻止动画?
【发布时间】:2010-06-25 15:59:26
【问题描述】:

我的应用程序有一个导航控制器,我不希望它有任何动画:

  • 要在推送视图时阻止动画,很简单,通过 pushViewController:animated: 方法

  • 但是当我点击这个子视图上的“返回”按钮时,有一个动画! KO!我可以做些什么来阻止这个动画?

【问题讨论】:

  • 为什么要用非标准行为破坏 UI?
  • 我并不是想用非标准的行为来破坏 UI。我只是不明白为什么 SDK 具有控制推送是否动画的功能,但没有具有相同的弹出控件。我觉得它不一致。
  • 非标准行为让我们成长:)

标签: iphone uinavigationcontroller back-button


【解决方案1】:

这会阻止默认动画。

- (void)viewWillDisappear:(BOOL)animated {
    [UIView setAnimationsEnabled: NO];
}

- (void)viewDidDisappear:(BOOL)animated {
    [UIView setAnimationsEnabled: YES];
}

如果您需要自定义动画

- (void)viewWillDisappear:(BOOL)animated {
    [UIView setAnimationsEnabled: NO];

    CATransition *transition = [CATransition animation];
    transition.duration = 0.3;
    transition.type = kCATransitionFade;
    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
}

- (void)viewDidDisappear:(BOOL)animated {
    [UIView setAnimationsEnabled: YES];
}

【讨论】:

    【解决方案2】:

    更优雅的一个类别。这假设您在应用程序委托中设置了导航控制器对象。只需将其放在根视图控制器中的 @implementaion 之前即可。

    #import "AppDelegate.h"
    
    @implementation UINavigationBar (custom)
    - (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated;
    {
    
        AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    
        [delegate.navController popViewControllerAnimated:NO];
    
        return TRUE;
    }
    
    
    @end
    

    【讨论】:

    • 感谢您的回答,我刚刚尝试过,它确实有效,但令人惊讶的是,您为期待 UINavigationItem 的东西返回 TRUE。
    • 此外,如果您的应用中有 1 个且只有 1 个导航控制器,则此解决方案有效。它不适用于多个导航控制器。
    • 它刚刚在我脑海中浮现。请解释。我是新手。塔尔斯
    • 类别添加或替换类中的方法。此类别方法替换了 - (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated;方法并改变行为。
    • -1 用于使用 TRUE 而不是 YES。顺便说一句,返回类型是 UINavigationsItem *,而不是布尔值
    【解决方案3】:

    我来 SO 是为了寻找一个更优雅的解决方案,但这是我迄今为止(成功地)这样做的方式。

    基本思路:

    1. 不要使用 UINavigationController;而是使用它的组成部分(例如 UINavigationBar)并自己完成工作
    2. 触发导航栏以与您自己的自定义动画并行进行动画处理(或者,如果您根本不需要动画,则不触发)

    缺点:

    1. UINavigationController 会自动处理一些其他事情,例如内存加载/卸载。此外,它被“硬编码”到所有 UIViewController 中——它们总是引用包含它们的 UINavigationController。仅仅因为 Apple 没有提供设置自定义动画的钩子,就将所有这些都扔掉是一种耻辱。

    代码 - 在哪个类中接管动画:

    UINavigationItem *backItem = [[UINavigationItem alloc] initWithTitle:@"Back"];
    [navigationController.navigationBar pushNavigationItem:backItem animated:TRUE];
    // next line only needed if you want a custom back anim too
    navigationController.navigationBar.delegate = self;
    

    ...如果您还想插入自定义后退动画,则需要上面的最后一行,这样您就可以收听导航栏,并做出并行反应,如下所示:

    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
    {
        // trigger your custom back animation here
    
        return TRUE;
    }
    

    【讨论】:

    • 感谢您的回答!但你是对的:我懒得扔掉所有 UINavigationController 功能,我更喜欢让动画发生;)
    • *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在控制器管理的 UINavigationBar 上手动设置委托。”
    • 这里发生了什么。我什么都听不懂。请有人帮助我
    【解决方案4】:

    您不应该这样做,但是您可以通过在 viewController 中创建自定义 leftBarButtonItem 来覆盖标准行为。

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Back" style: UIBarButtonItemStylePlain target:self action:@selector(backButtonPressed)];
    [[self navigationItem] setLeftBarButtonItem:item];
    [item release];
    
    - (void)backButtonPressed
    {
        [[self navigationContoller] popViewControllerAnimated:NO];
    }
    

    documentation 表示您应该只在显示导航控制器视图之前通过NO。

    请记住,不符合 iPhone 界面指南的应用程序将不会被应用商店接受。

    【讨论】:

    • 该代码有问题,即使这样也只能部分工作。你不会得到“箭头”形状的按钮。代码中的错字 - 第 1 行缺少“]”。此外,第 2 行中的代码不正确 - 我相信它应该是:“[self.navigationItem setLeftBarButtonItem:item];” w.r.t. “这是否被 Apple 接受”: 1. 这不是真的 - 许多违反 HIG 的应用程序都被接受;许多苹果自己的应用程序公然违反它。 2.任何时候你想要做一个自定义的push/pop动画对,你需要禁用默认的(因为Apple没有提供公共API来覆盖它)。
    • 感谢您的回答。不过,我同意 Adam 的观点:“箭头”形状是 iPhone 应用程序中必须具备的。
    • 您可以随时重新创建箭头图像。我认为这是一种相当普遍的做法,因为苹果没有给你一种以编程方式制作的方法。
    【解决方案5】:

    我刚刚回答了另一个相关问题,该问题描述了如何easily create a custom back button that replicates the look of the standard iOS (iPhone / iPad) UI back bar button item,但允许添加其他功能。按照falconcreek's answer 中的建议,在backButtonPressed 方法中,只需添加:

    [[self navigationController] popViewControllerAnimated:NO];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多