LargeTitles UIScrollView does not support multiple observers implementing _scrollViewWillEndDraggingWithVelocity:targetContentOffset

那年仲夏 提交于 2019-12-07 02:51:04

问题


I have implemented large titles in my app with the following code:

if #available(iOS 11.0, *) {
            navigationController?.navigationBar.prefersLargeTitles = true
            navigationItem.largeTitleDisplayMode = .always
        } else {
            // Fallback on earlier versions
        }
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.y <= 0 {
        if #available(iOS 11.0, *) {
            self.navigationItem.largeTitleDisplayMode = .always
        } else {
            // Fallback on earlier versions
        }
    } else {
        if #available(iOS 11.0, *) {
            self.navigationItem.largeTitleDisplayMode = .never
        } else {
            // Fallback on earlier versions
        }
    }
    self.navigationController?.navigationBar.setNeedsLayout()
    self.view.setNeedsLayout()
    UIView.animate(withDuration: 0.01, animations: {
        self.navigationController?.navigationBar.layoutIfNeeded()
        self.view.layoutIfNeeded()
    })
}

I am able to successfully toggle between views on a tabbar but when I push a view ontop of the tabbar controller and then pop it off using this code:

_ = self.navigationController?.popViewController(animated: true)

I get this crash when I toggle between views on the tabbar again: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'ERROR: UIScrollView does not support multiple observers implementing _scrollViewWillEndDraggingWithVelocity:targetContentOffset:'


回答1:


I've the same problem and I fixed it by removing this line from AppDelegate:

UINavigationBar.appearance().prefersLargeTitles = true

and handle prefersLargeTitles inside viewDidLoad in certain UIViewController




回答2:


I found the solution. You have to set the first navigation controller to not use large titles.

The point is that now UIScrollView has only one observer (navigationController) implementing _scrollViewWillEndDraggingWithVelocity.

if (@available(iOS 11.0, *)) {

    self.navigationController.navigationBar.prefersLargeTitles = FALSE;
    self.navigationController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;

}



回答3:


The problem happened when the tableview was still scrolling when I went to another view. I fixed the problem by setting a bool in the scrollViewDidScroll that disables any scrolling when the segue is started.

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if viewIsVisible {
            if scrollView.contentOffset.y <= 0 {
                if #available(iOS 11.0, *) {
                    self.navigationItem.largeTitleDisplayMode = .always
                } else {
                    // Fallback on earlier versions
                }
            } else {
                if #available(iOS 11.0, *) {
                    self.navigationItem.largeTitleDisplayMode = .never
                } else {
                    // Fallback on earlier versions
                }
            }
            self.navigationController?.navigationBar.setNeedsLayout()
            self.view.setNeedsLayout()
            UIView.animate(withDuration: 0.01, animations: {
                self.navigationController?.navigationBar.layoutIfNeeded()
                self.view.layoutIfNeeded()
            })
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        self.viewIsVisible = false
}


来源:https://stackoverflow.com/questions/47871426/largetitles-uiscrollview-does-not-support-multiple-observers-implementing-scrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!