简体   繁体   English

iOS 11大标题更改事件

[英]iOS 11 Large Title change event

I want to get the event when iOS 11 large title changes. 我想在iOS 11大标题更改时获取此事件。 ie When it changes the place to & from navigation bar when user scrolls the view. 即,当用户滚动视图时,它将位置更改为导航栏和从导航栏更改。 I've checked the UINavigationBar class but nothing I can get it from. 我已经检查了UINavigationBar类,但我无法从中获取它。

The screen design I want to implement is like when Large title is visible I want transparent Navigation bar but when title scrolled up to navigation bar I want nav bar with solid colour. 我要实现的屏幕设计就像大标题可见时我想要透明导航栏但是当标题滚动到导航栏时我想要纯色的导航栏。

It can done by getting current height of UINavigationBar by scrollViewDidScroll func. 它可以通过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
    }
}

I have added this observer in my UIViewController's subclass's ViewWillAppear. 我在UIViewController的子类的ViewWillAppear中添加了这个观察者。 and setting the color according to its height as below: 并根据其高度设置颜色如下:

In ViewWillAppear: 在ViewWillAppear中:

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

In viewWillDisappear: 在viewWillDisappear中:

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

A small improvement on Piyush Hirpara answer (regarding performances), is to subclass your navigationBar and only update on layoutSubviews : 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
            }
        }
    }
}

Note that the value of 44 for the frame.height may need to be adjusted in some circumstances. 请注意,在某些情况下,可能需要调整frame.height的值44 I have it at 60 for instance in my configuration on an iPhone X. 例如,我在iPhone X上的配置为60

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM