【问题标题】:UISearchController wrong animation on swipe back then disappearingUISearchController 滑动时错误的动画然后消失
【发布时间】: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

标签: ios iphone xcode navigationbar searchbar


【解决方案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
        }
        

        【讨论】:

          猜你喜欢
          • 2012-03-07
          • 1970-01-01
          • 1970-01-01
          • 2011-01-12
          • 2014-09-21
          • 1970-01-01
          • 2020-05-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多