pushViewController调用的UIViewController的出现动画显示两次

Posted

技术标签:

【中文标题】pushViewController调用的UIViewController的出现动画显示两次【英文标题】:Appear animation of UIViewController called by pushViewController displayed twice 【发布时间】:2016-07-01 15:53:16 【问题描述】:

我有 UISearchBar,当我单击 UISearchBar 中的搜索按钮时,我想显示另一个 UIViewController。我正在使用以下方法:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar

    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main"
                                                         bundle:nil];
    UIViewController *add =
    [storyboard instantiateViewControllerWithIdentifier:@"mainMenuViewController"];

    [self.navigationController pushViewController:add animated:YES];

问题是 UIViewController 的出现动画被调用了两次。我看到旧控制器从右侧向左滑动两次。

现在,如果我在单击某些常规 UIButton 时使用相同的代码显示新控制器,动画问题就消失了。所以它似乎与 UISearchBar 有某种关系。

searchBarSearchButtonClicked 的委托方法只调用一次。

重现问题的代码非常少,可能我稍后会附上示例项目。

但是带有搜索栏的 UIVIewCOntroller 看起来像这样:

- (void)viewDidLoad 
    [super viewDidLoad];

    UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
    searchBar.placeholder = NSLocalizedString(@"search a pub or a place", nil);
    searchBar.delegate = self;
    [self.navigationItem setTitleView:searchBar];



- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar

    DLog(@"Filter searchBarSearchButtonClicked");
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main"
                                                         bundle:nil];
    UIViewController *add =
    [storyboard instantiateViewControllerWithIdentifier:@"mainMenuViewController"];

    [self.navigationController pushViewController:add animated:YES];

ios 8 和 9 都存在问题。

编辑:

我上传了示例项目here。它非常简约。

编辑2:

如果我这样呈现控制器,而不是通过导航控制器,动画只会显示一次。 (虽然这是另一个动画 - 从下往上,前一个是从右到左)。但我需要通过导航控制器来完成。所以问题似乎与 UISearchBar Search clicked + Navigation Controller 有关。

[self presentViewController:add
                   animated:YES
                 completion:nil];

当然我也可以这样不带动画的调用:

[self.navigationController pushViewController:add animated:NO];

但是如果我想要动画怎么办。

编辑3:

我尝试通过 segue 显示第二个控制器,但没有帮助。

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar

    [self performSegueWithIdentifier:@"seg1" sender:self];

编辑4:

我已经向 Apple 报告了这个错误,因为我猜这一定是 UIKit 中的错误。无论如何,如果有人能找到解决方法,那就太好了。

【问题讨论】:

也许有些事情与 UISearchController 的解雇混淆了。要尝试的一件事是将您的按钮委托代码移动到具有简单签名的方法中,然后使用 self performSelector 调用它。 感谢您的想法,我已经尝试过了,但问题仍然存在。 【参考方案1】:

我在文档中没有找到任何说明禁止将搜索栏作为导航项 titleView 的内容,但这是导致不需要的动画的原因。

将按钮添加为子视图,推送时会出现单个动画。快速解决方法是在继续演示之前将其删除...

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 

    [self.navigationItem.titleView removeFromSuperview];

    // and so on with the OP code...

奇怪的是,这修复了额外的动画问题,但实际上并没有删除搜索栏。删除后立即检查 titleView 显示搜索栏仍然存在。

【讨论】:

伟大的收获!所以我不知道我是否应该依赖那个 hacky 解决方案,因为它看起来也有问题(如果它不删除视图) - 但它有效,是的。我可以将哪个按钮添加为子视图以及在哪里? 也许我可以依赖那个 hacky 解决方案,比如如果它在编译时工作,它会永远工作,无论苹果是否会在未来的某个版本中修复删除。我不确定。取决于 UIKit 是链接到已编译的应用程序,还是动态调用。 很高兴它有帮助。我处理这个问题的方法是使用文档中推荐的 UISearchController 。这里建议的 hack 是绕过搜索栏作为标题视图的原始 hack。 好的,谢谢。我有好消息!我发现如果您“聚焦” UINavigationBar 然后单击一些常规 UIButton 以显示新控制器,也会发生动画错误。 (如果 UINavigationbar 没有聚焦,效果很好!)这意味着问题也与焦点有关!这意味着,如果你这样称呼,问题也得到了解决:[self.navigationItem.titleView resignFirstResponder];在显示新控制器之前。但你的想法也很有帮助。

以上是关于pushViewController调用的UIViewController的出现动画显示两次的主要内容,如果未能解决你的问题,请参考以下文章

pushviewcontroller 动画而不实际调用 pushviewcontroller

viewWillAppear 调用但 viewDidAppear 在 pushViewController 之后未调用

在 Swift 中的 presentViewController 之后调用 pushViewController

关于presentViewController 后调用pushViewController

pushViewController调用的UIViewController的出现动画显示两次

CosmicMind/Material - 如何在 NavigationDrawerController 中调用 pushViewController?