美文网首页
iOS仿微信和QQ导航栏加菊花转

iOS仿微信和QQ导航栏加菊花转

作者: _moses | 来源:发表于2017-08-20 20:44 被阅读2472次
    QQ导航栏.png
    #import <UIKit/UIKit.h>
    
    @interface NavigationController : UINavigationController
    // 设置为YES即显示菊花,设置为NO即隐藏菊花
    @property (nonatomic, assign) BOOL animate;
    
    @end
    
    #import "NavigationController.h"
    
    @interface NavigationController ()
    
    @property (nonatomic, strong, nullable) UIActivityIndicatorView *indicatorView;
    
    @end
    
    @implementation NavigationController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 导航栏颜色(白色)
        self.navigationBar.barTintColor = [UIColor whiteColor];
        // 导航栏title颜色(黑色)
        [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}];
        // 导航栏返回按钮字体颜色(黑色)
        self.navigationBar.tintColor = [UIColor blackColor];
        // 灰色菊花
        self.indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
        [self.navigationBar addSubview:self.indicatorView];
    }
    
    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
        // 进入新页面,title长度变化后,重新调整菊花位置
        // Xcode 9编辑器,请用如下代码,兼容iOS8-iOS11
        for (UIView *subView in self.navigationBar.subviews) {
            if ([NSStringFromClass([subView class]) isEqualToString:@"_UINavigationBarContentView"]) {
                for (UIView *sub in subView.subviews) {
                    if ([sub isKindOfClass:[UILabel class]] && [[sub valueForKey:@"text"] isEqualToString:self.viewControllers.lastObject.title]) {
                        self.indicatorView.frame = CGRectMake(sub.frame.origin.x - 30, 0, 30, 30);
                        self.indicatorView.center = CGPointMake(self.indicatorView.center.x, sub.center.y);
                    }
                }
            } else if ([NSStringFromClass([subView class]) isEqualToString:@"UINavigationItemView"]) {
                if ([[subView valueForKey:@"title"] isEqualToString:[self.viewControllers lastObject].title]) {
                    self.indicatorView.frame = CGRectMake(subView.frame.origin.x - 30, 0, 30, 30);
                    self.indicatorView.center = CGPointMake(self.indicatorView.center.x, subView.center.y);
                }
            }
        }
        // Xcode 8及以下编辑器,请用如下代码,兼容iOS8-iOS11
        for (UIView *subView in self.navigationBar.subviews) {
            if ([NSStringFromClass([subView class]) containsString:@"UINavigationItemView"]) {
                if ([[subView valueForKey:@"title"] isEqualToString:[self.viewControllers lastObject].title]) {
                    self.indicatorView.frame = CGRectMake(subView.frame.origin.x - 30, 0, 30, 30);
                    self.indicatorView.center = CGPointMake(self.indicatorView.center.x, subView.center.y);
                }
            }
        }
    }
    
    - (void)setAnimate:(BOOL)animate {
        _animate = animate;
        if (animate) {
            [self.indicatorView startAnimating];
        } else {
            [self.indicatorView stopAnimating];
        }
    }
    
    @end
    

    注意:此方法有2个BUG:

    BUG:由后面控制器边缘滑动返回前面控制器时,撤销返回后,菊花位置会排在前一个页面的title前面。
    解决办法:项目所有控制器继承自自定义控制器BaseViewController,在BaseViewController的viewDidAppear方法中调用导航控制器的viewDidLayoutSubviews方法。

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        [self.navigationController viewDidLayoutSubviews];
    }
    

    BUG:还是菊花的位置问题,如果相邻的两个控制器的title都比较长,这时如果返回按钮和title的位置间隔小于30,菊花会和返回按钮重合
    解决办法:无(逻辑过于复杂,我选择把title设置短一些😂)

    相关文章

      网友评论

          本文标题:iOS仿微信和QQ导航栏加菊花转

          本文链接:https://www.haomeiwen.com/subject/sgxqdxtx.html