UISearchController 滑动时错误的动画然后消失

Posted

技术标签:

【中文标题】UISearchController 滑动时错误的动画然后消失【英文标题】:UISearchController wrong animation on swipe back then disappearing 【发布时间】:2019-06-02 03:48:15 【问题描述】:

为了简短起见,我有一个隐藏了导航栏的主视图控制器,从该 VC 的导航控制器中,我推送了另一个导航栏可见的视图控制器。然后我将一个 searchController 添加到 navigationItem 以在我向下滚动时添加 searchBar。一切正常,直到您向后滑动弹出 VC。

导航栏会随着 VC 以动画方式离开屏幕,但 searchBar 会以动画方式呈现,就好像它在原地上升一样。更糟糕的是,如果我取消滑动弹出,整个 searchBar 就会消失,而是出现一个黑色视图(我认为 searchController 背景属于任何视图背景)。

我尝试了所有方法,只是几行代码,但我一直在努力解决这个问题。我知道我可以禁用滑动弹出,但我不希望这样(+ 即使按同样奇怪的方式按下 searchBar 动画),我不想以任何其他方式添加 searchBar。

在附加的视频中,我只是用手指滑动来显示动画。

- (void)viewDidLoad 
    [super viewDidLoad];
    self.definesPresentationContext = YES;
    [self.navigationController setNavigationBarHidden:NO];

    if (@available(ios 11.0, *)) 
        self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
        _searchController.delegate = self;
        _searchController.searchResultsUpdater = self;
        _searchController.searchBar.placeholder = @"Search";
        self.navigationItem.searchController = _searchController;
        self.navigationItem.hidesSearchBarWhenScrolling = YES;
    

【问题讨论】:

显示一些代码,如何添加搜索栏 当然,我编辑了问题以添加代码。 有人吗?有什么事吗? 能分享一下你的项目代码吗? @HarshalWani 我在这里上传了一个示例项目:github.com/DanielKlink/SearchbarNavigationPopIssue 【参考方案1】:

我认为添加额外的UISearchController 是一种矫枉过正。您始终可以通过情节提要或代码将独立的 UISearchbar 添加到您的视图控制器,并将您的搜索栏托管视图控制器作为该搜索栏的代表。

类似这样的:

    self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 0, NAVBAR_HEIGHT)];   
    self.searchBar.delegate = self;
    self.view.addSubView(self.searchBar);

这样,导航项与搜索栏的耦合就会消失,希望问题能得到解决。

【讨论】:

【参考方案2】:

将搜索栏放在导航项的标题视图中,而不是将UISearchController 分配给UINavigationItem's searchController

替换

navigationItem.searchController

navigationItem.titleView = searchController?.searchBar

更新答案:

问题是由于用于隐藏NavigationBar的方法 隐藏NavigationBar有多种方法

self.navigationController?.setNavigationBarHidden(false, animated: true)
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.isNavigationBarHidden = false

而且您似乎只使用了 setter 属性来隐藏 MasterViewController

self.navigationController?.setNavigationBarHidden(true, animated: true)

相反,使用 isNavigationBarHidden 既是 setter 又是 getter。

override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        self.navigationController?.isNavigationBarHidden = true
    

override func viewWillDisappear(_ animated: Bool) 
        super.viewWillDisappear(animated)
        self.navigationController?.isNavigationBarHidden = false
    

并且还从DetailViewController 中删除setNavigationBarHidden

干杯!

【讨论】:

感谢您的回答,这可能是肯定的,但在我的情况下,我已经为 navigationItem 设置了自定义 titleView。我需要将 searchBar 作为下拉菜单。这就是为什么有必要将其设置为 navigationItem.searchController。问题仍然存在:如何避免弹出动画损坏,同时解决第二个viewcontroller出现后searchBar消失的问题? SearchBar 由于在 MasterVC 上设置为隐藏导航栏而消失。尽量不要将 NavigationBar 设置为隐藏。它会正常工作【参考方案3】:

我在这里尝试了答案,但没有一个没有按我的意愿工作。以下解决方案对我有用。

对于错误的动画,我在 viewController 中使用 searchBar 执行了以下操作:

override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)

    let containerView = transitionCoordinator?.containerView
    let currentPosition = self.navigationItem.searchController?.searchBar.superview?.frame.origin.x
    transitionCoordinator?.animateAlongsideTransition(in: containerView, animation:  (context) in
        if context.viewController(forKey: .to) is PreviousViewController 
            self.navigationItem.searchController?.searchBar.superview?.frame.origin.x = self.view.frame.size.width

        

    , completion:  (context) in
        self.navigationItem.searchController?.searchBar.superview?.frame.origin.x = currentPosition ?? 0
    )

对于 searchBar 的消失,我稍微滚动了 tableView,让 searchBar 重新出现。问题是 searchBar 已从其 superView 中完全删除。但是有了这个微小的滚动“动画”,搜索栏又回来了。不是很酷,但很有效:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)

    //workaround for showing the searchbar again if popgesture was canceled
    var offset = self.tableView.contentOffset
    offset.y -= 0.5
    UIView.animate(withDuration: 0.05, animations: 
        self.tableView.setContentOffset(offset, animated: false)
    , completion: _ in
        offset.y += 0.5
        self.tableView.setContentOffset(offset, animated: false)
    )

【讨论】:

【参考方案4】:

我认为这是 iOS 11、12 的错误,因为它在 iOS 13 beta 7 中完美运行。

【讨论】:

【参考方案5】:

我已经尝试了很多来寻找解决这个问题的解决方案,我终于找到了这个解决方案,

尝试使用它:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    navigationItem.hidesSearchBarWhenScrolling = false

【讨论】:

以上是关于UISearchController 滑动时错误的动画然后消失的主要内容,如果未能解决你的问题,请参考以下文章

UISearchController + UICollectionView 错误

关闭并滑动以关闭搜索控制器处于活动状态的问题

UISearchController 模态表示样式错误

UISearchController 搜索栏位置下降 64 点

UISearchController 位置错误,因为带有 tableview 插图

NavigationItem iOS 11 Apple 方式中的 UISearchController