UISearchController在向后滑动时出现错误的动画,然后消失了。

9
简单来说,我有一个主视图控制器,其中导航栏被隐藏。从该 VC 的导航控制器中,我推出另一个具有可见导航栏的视图控制器。然后,我将 searchController 添加到 navigationItem 中,以便在向下滚动时添加 searchBar。一切都正常工作,直到您滑动返回弹出 VC。
导航栏会与 VC 一起动画离开屏幕,但 searchBar 将动画显示为在原地上升。更糟糕的是,如果我取消滑动以弹出,则整个 searchBar 将消失,并出现黑色视图(我认为是 searchController 背景或任何视图背景)。
我尝试了所有方法,这只是几行代码,但我一直在解决这个问题。我知道我可以禁用滑动以弹出,但我不想这样做(即使按下返回键,searchBar 也会以同样奇怪的方式进行动画处理),而且我不想以其他方式添加 searchBar。
在附加的视频中,我只是用手指滑动以显示动画。

desc

- (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;
    }
}

展示一些代码,演示如何添加搜索栏。 - Scriptable
当然,我编辑了问题以添加代码。 - Eph Bee
有人吗?有什么东西? - Eph Bee
请问您能分享一下您的项目代码吗? - Harshal Wani
@HarshalWani 我在这里上传了一个示例项目:https://github.com/DanielKlink/SearchbarNavigationPopIssue - Klinki
这现在在iOS 13上已经正常工作了。 - Ahmad Farrag
5个回答

0
我认为这是iOS 11、12的一个bug,因为在iOS 13 beta 7中它完美地工作。

0

添加额外的UISearchController我认为是过度的。您可以始终通过Storyboard或代码向视图控制器添加独立的UISearchbar,并将托管搜索栏的视图控制器设置为该搜索栏的委托。

像这样:

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

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


0
将搜索栏放置在导航项的标题视图中,而不是将UISearchController分配给UINavigationItem的searchController。
替换

navigationItem.searchController

使用

navigationItem.titleView = searchController?.searchBar

更新的答案:

问题是由于隐藏NavigationBar的方法不同。 有不同的方法来隐藏NavigationBar

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

看起来你在MasterViewController中使用了只有setter的属性来隐藏。

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是必要的。问题仍然是:我们如何避免破碎的弹出动画,并修复第二个视图控制器返回后搜索栏消失的问题? - Klinki
搜索栏由于主视图控制器设置了隐藏导航栏而消失。尝试不要设置隐藏导航栏,它将正常工作。 - Harshal Wani

0

我尝试了这里的答案,但是它们都没有按照我想要的方式工作。以下解决方案对我有用。

对于错误的动画,我在带有搜索栏的viewController中执行了以下操作:

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
    })
}

为了让搜索栏重新出现,我稍微滚动了一下表格视图。问题是搜索栏完全从其父视图中移除了。但是通过这个微小的滚动“动画”,搜索栏又回来了。虽然不太酷,但是它起作用了:

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)
    })
}

0

我尝试了很多方法来解决这个问题,最终找到了这个解决方案,

尝试使用它:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接