【问题标题】:iOS 11 Large Title change eventiOS 11 大标题更改事件
【发布时间】:2018-02-20 12:14:41
【问题描述】:

我想在 iOS 11 大标题更改时获取该事件。即当用户滚动视图时,它将位置更改为导航栏和导航栏。我已经检查了 UINavigationBar 类,但我无法从中得到它。

我想要实现的屏幕设计就像当大标题可见时我想要透明导航栏但当标题向上滚动到导航栏时我想要纯色导航栏。

【问题讨论】:

    标签: ios uinavigationbar ios11


    【解决方案1】:

    可以通过scrollViewDidScroll函数获取UINavigationBar的当前高度。

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
    
        //Get current height of navigation bar when tableview/collectionview/scrollview did scroll
        guard let navBarHeight = navigationController?.navigationBar.frame.height else {
            return
        }
    
        //Compare with standard height of navigation bar.
        if navBarHeight > 44.0 {
            self.navigationController?.navigationBar.shadowImage = UIImage()
            self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
            self.navigationController?.navigationBar.barTintColor = .clear
        } else {
            self.navigationController?.navigationBar.shadowImage = nil
            self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
            self.navigationController?.navigationBar.barTintColor = .green
        }
    }
    

    【讨论】:

    • 感谢您的回答。我有一个想法,可以在更改时在导航栏框架上添加观察者,然后使用您上面提到的条件。
    【解决方案2】:

    我已经在我的 UIViewController 的子类的 ViewWillAppear 中添加了这个观察者。并根据其高度设置颜色如下:

    在 ViewWillAppear 中:

    UINavigationBar *navBar = self.navigationController.navigationBar;
    [navBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
    

    在视图中将消失:

    UINavigationBar *navBar = self.navigationController.navigationBar;
    [navBar removeObserver:self forKeyPath:@"frame" context:NULL];
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"frame"]) {
        [self setNavigationBarColour];;
    }
    

    }

    - (void)setNavigationBarColour
    {
        UINavigationBar *navBar = self.navigationController.navigationBar;
        CGFloat height = navBar.bounds.size.height;
        if(height>44)
        {
            [navBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
            [navBar setTranslucent:YES];
            [navBar setShadowImage:[UIImage new]];
        }
        else
        {
            [navBar setBackgroundImage:[[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
            [navBar setTranslucent:NO];
            [navBar setShadowImage:[[UINavigationBar appearance] shadowImage]];
        }
    }
    

    【讨论】:

    • 出于性能原因,您可能希望将您的导航栏子类化并覆盖layoutSubviews:这样您仍然可以观察到大标题何时更改其可见性,并且您对setNavigationBarColour 的调用会更少.
    【解决方案3】:

    对 Piyush Hirpara 答案的一个小改进(关于性能)是子类化您的 navigationBar 并且仅在 layoutSubviews 上更新:

    class ObservingLargeTitleNavigationBar: UINavigationBar {
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            updateLargeTitle()
        }
    
        private func updateLargeTitle() {
            if #available(iOS 11.0, *) {
                if frame.height > 44 {
                    // code logic when large title is visible
                } else {
                    // code logic when large title is hidden
                }
            }
        }
    }
    

    请注意,frame.height44 的值在某些情况下可能需要调整。我在60 有它,例如在我的 iPhone X 配置中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-04
      • 2018-04-14
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多