代码之家  ›  专栏  ›  技术社区  ›  Piyush Hirpara

iOS 11大型标题更改事件

  •  5
  • Piyush Hirpara  · 技术社区  · 6 年前

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

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

    3 回复  |  直到 6 年前
        1
  •  4
  •   Jay Patel    6 年前

    它可以通过scrollViewDidScroll func获取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
  •  4
  •   Piyush Hirpara    6 年前

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

    在视图中将显示:

    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]];
        }
    }
    
        3
  •  2
  •   App Dev Guy    4 年前

    Piyush Hirpara答案(关于性能)的一个小改进是对导航栏进行子类化,并且只更新 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
                }
            }
        }
    }
    

    请注意 44 对于 frame.height 在某些情况下可能需要调整。我在 60 例如,在我的iPhone X配置中。