美文网首页程序开发
iOS开发丨使用BaseViewController作为项目视图

iOS开发丨使用BaseViewController作为项目视图

作者: 炼心术师 | 来源:发表于2019-12-27 17:24 被阅读0次

    在iOS开发中,有时候需要很频繁的去设置一个ViewController的属性,如导航栏返回按钮、右侧按钮、背景色、分割线等杂七杂八的功能,使用一个基类BaseViewController就能够解决掉不少麻烦,如下使用方式:

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        self.navigationItem.title = NSLocalizedString(@"标题", nil);
        [self setTitleColor:[UIColor colorWithHexString:@"#13243C"] font:[UIFont systemFontOfSize:18 weight:UIFontWeightRegular]];  // 设置标题颜色和字体
        [self setNavBgColor:[UIColor whiteColor]];  // 设置导航栏背景色
        [self setNavShadowColor:[UIColor clearColor]];  // 设置导航栏分割线颜色
        [self setNavLeftImage:@"back_black"];  // 设置导航栏返回图片
    }
    

    BaseViewController.h代码如下:

    #import <UIKit/UIKit.h>
    #import "BottomPresentationController.h"
    
    #define MoreNavLeftTag  10000
    #define MoreNavRightTag 20000
    
    @interface BaseViewController : UIViewController <UIViewControllerTransitioningDelegate, UIGestureRecognizerDelegate>
    
    @property (strong, nonatomic) BottomPresentationController   *presentCtrl;
    @property (assign, nonatomic) CGFloat presentHeight;         // 自定义弹窗的高度
    @property (strong, nonatomic) UIView   *NavHintView;         //导航栏下方提示框
    @property (strong, nonatomic) NSString *NavLeftImage;        //导航左按钮图片名
    @property (strong, nonatomic) NSString *NavRightImage;       //导航右按钮图片名
    @property (strong, nonatomic) NSArray  *NavLeftImageArray;   //导航左侧多按钮图片
    @property (strong, nonatomic) NSArray  *NavRightImageArray;  //导航右侧多按钮图片
    @property (strong, nonatomic) NSString *titleStr;            //导航titleView;
    @property (strong, nonatomic) NSString *titleImage;          //导航titleView;
    @property (strong, nonatomic) UIColor  *titleColor;          //导航title颜色
    @property (strong, nonatomic) UIColor  *NavBgColor;          //导航栏颜色
    @property (strong, nonatomic) UIColor  *NavShadowColor;      //导航下面线的颜色
    @property (assign, nonatomic) BOOL     isSlidingReturn;      //是否开启侧滑返回功能(默认为YES)
    @property (strong, nonatomic) UIBarButtonItem *leftItem;
    @property (strong, nonatomic) UIBarButtonItem *rightItem;
    
    - (void)keyboardWillShow:(NSNotification *)notif;
    - (void)keyboardWillHide:(NSNotification *)notif;
    - (void)keyboardWillChangeFrame:(NSNotification *)notif;
    
    /**
     * 设置导航条Title颜色
     */
    - (void)setTitleColor:(UIColor *)titleColor font:(UIFont *)font;
    /**
     * 导航左侧按钮点击方法
     */
    - (void)tapNavLeftBtn:(UIButton *)sender;
    /**
     * 导航右侧按钮点击方法
     */
    - (void)tapNavRightBtn:(UIButton *)sender;
    /**
     * 导航多个左侧按钮点击方法(tag值越小,越靠前, tag值从10000开始)
     */
    - (void)tapMoreNavLeftBtn:(UIButton *)sender;
    /**
     * 导航多个右侧按钮点击方法(tag值越小,越靠前, tag值从20000开始)
     */
    - (void)tapMoreNavRightBtn:(UIButton *)sender;
    /// 重载视图
    - (void)reloadView;
    /// 加载弹窗视图
    - (void)presentBottom:(BaseViewController *)bottomVC completion:(void (^)(void))completion;
    
    @end
    

    BaseViewController.m代码如下:

    #import "BaseViewController.h"
    
    @implementation BaseViewController
    
    #pragma mark 默认旋转方向
    - (BOOL)shouldAutorotate {  // 是否支持旋转屏幕
        return NO;
    }
    
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {  // 支持哪些方向
        return UIInterfaceOrientationMaskPortrait;
    }
    
    #pragma mark 默认状态栏
    - (UIStatusBarStyle)preferredStatusBarStyle {
        return UIStatusBarStyleDefault;
    }
    
    - (BOOL)prefersStatusBarHidden {
        return NO;
    }
    
    - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
        return UIStatusBarAnimationNone;
    }
    
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        // 去掉返回按钮显示的文字
        UIBarButtonItem *backItem = [[UIBarButtonItem alloc] init];
        backItem.title = @"";
        self.navigationItem.backBarButtonItem = backItem;
        [self.navigationController setNavigationBarHidden:NO animated:animated];
        self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
        if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
            // 支持右滑返回上一级的代理
            self.navigationController.interactivePopGestureRecognizer.delegate = self;
            self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        }
        self.automaticallyAdjustsScrollViewInsets = NO;
        [self setNavShadowColor:[UIColor clearColor]];
        // 监听键盘的弹出和退出
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [self setNavBgColor:[UIColor whiteColor]];
        [self setNavShadowColor:[UIColor clearColor]];
        // 移除监听键盘的弹出和退出
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
        [self.view endEditing:YES];  // 取消键盘编辑状态
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.view setNeedsLayout];
        [self.view layoutIfNeeded];
        self.view.backgroundColor = [UIColor whiteColor];
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognize {
        if (self.navigationController.viewControllers.count == 1) {
            return NO;
        }
        else {
            return YES;
        }
    }
    
    - (void)keyboardWillShow:(NSNotification *)notif {
    }
    
    - (void)keyboardWillHide:(NSNotification *)notif {
    }
    
    - (void)keyboardWillChangeFrame:(NSNotification *)notif {
    }
    
    - (void)reloadView {
    }
    
    #pragma mark 设置导航条Title Label
    - (void)setTitleStr:(NSString *)titleStr font:(UIFont *)font color:(UIColor *)color {
        _titleStr = titleStr;
        
        UILabel *titleLab = [[UILabel alloc] init];
        titleLab.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width-100, 30);
        titleLab.text = titleStr;
        titleLab.font = font;
        titleLab.textColor = color;
        titleLab.adjustsFontSizeToFitWidth = YES;
        
        self.navigationItem.titleView = titleLab;
    }
    
    #pragma mark 设置导航条Title Button
    - (void)setTitleImage:(NSString *)titleImage {
        _titleImage = titleImage;
        
        UIButton *titleBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 41.0f, 21.0f)];
        // 高亮的时候不要自动调整图标
        titleBut.adjustsImageWhenHighlighted = NO;
        titleBut.titleLabel.font = [UIFont boldSystemFontOfSize:16.0f];
        titleBut.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        titleBut.imageView.contentMode = UIViewContentModeCenter;
        [titleBut setImage:[UIImage imageNamed:titleImage] forState:UIControlStateNormal];
        
        self.navigationItem.titleView = titleBut;
    }
    
    #pragma mark 设置导航条Title颜色
    - (void)setTitleColor:(UIColor *)titleColor font:(UIFont *)font {
        if (!titleColor) {
            return;
        }
        _titleColor = titleColor;
        // 设置标题属性
        NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
        textAttrs[NSForegroundColorAttributeName] = titleColor;
        textAttrs[NSFontAttributeName] = font;
        NSShadow *shadow = [[NSShadow alloc] init];
        shadow.shadowOffset = CGSizeZero;
        textAttrs[NSShadowAttributeName] = shadow;
        [self.navigationController.navigationBar setTitleTextAttributes:textAttrs];
    }
    
    #pragma mark 设置导航条背景颜色
    - (void)setNavBgColor:(UIColor *)NavBgColor {
        _NavBgColor = NavBgColor;
        // 设置导航栏背景
        UIImage *navImage = [self imageFromColor:NavBgColor rectSize:CGRectMake(0.0f, 0.0f, [UIScreen mainScreen].bounds.size.width, [[[UIDevice currentDevice] systemVersion] floatValue] < 7.0 ? 44.0f : 64.0f)];
        [self.navigationController.navigationBar setBackgroundImage:navImage forBarMetrics:UIBarMetricsDefault];
        self.navigationController.navigationBar.translucent = NO;
    }
    
    #pragma mark 设置导航条Shadow颜色
    - (void)setNavShadowColor:(UIColor *)NavShadowColor {
        _NavShadowColor = NavShadowColor;
        // 设置导航条Shadow颜色
        UIImage *navImage = [self imageFromColor:[UIColor clearColor] rectSize:CGRectMake(0.0f, 0.0f, [UIScreen mainScreen].bounds.size.width, 0.5)];
        self.navigationController.navigationBar.shadowImage = navImage;
    }
    
    #pragma mark 设置左边按钮
    - (void)setNavLeftImage:(NSString *)NavLeftImage {
        _NavLeftImage = NavLeftImage;
        _leftItem = [self itemWithIcon:NavLeftImage highIcon:nil target:self action:@selector(tapNavLeftBtn:)];
        self.navigationItem.leftBarButtonItem = _leftItem;
    }
    
    #pragma mark 设置右边按钮
    - (void)setNavRightImage:(NSString *)NavRightImage {
        _NavRightImage = NavRightImage;
        _rightItem = [self itemWithIcon:NavRightImage highIcon:nil target:self action:@selector(tapNavRightBtn:)];
        self.navigationItem.rightBarButtonItem = _rightItem;
    }
    
    #pragma mark 设置多个导航左按钮
    - (void)setNavLeftImageArray:(NSArray *)NavLeftImageArray {
        _NavLeftImageArray = NavLeftImageArray;
        NSMutableArray *itemArray = [NSMutableArray arrayWithCapacity:1];
        
        for (int i = 0; i < NavLeftImageArray.count; i++) {
            NSString *imageName = NavLeftImageArray[i];
            NSInteger itemTag = MoreNavLeftTag + i;
            UIBarButtonItem *item = [self moreItemWithIcon:imageName highIcon:nil target:self action:@selector(tapMoreNavLeftBtn:) tag:itemTag];
            item.tag = itemTag;
            [itemArray addObject:item];
        }
        self.navigationItem.leftBarButtonItems = itemArray;
    }
    
    #pragma mark 设置多个导航右按钮
    - (void)setNavRightImageArray:(NSArray *)NavRightImageArray {
        _NavRightImageArray = NavRightImageArray;
        NSMutableArray *itemArray = [NSMutableArray arrayWithCapacity:1];
        
        //NSEnumerationReverse 倒序遍历
        [NavRightImageArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSString *imageName = NavRightImageArray[idx];
            NSInteger itemTag = MoreNavRightTag + NavRightImageArray.count - (NavRightImageArray.count - idx);
            UIBarButtonItem *item = [self moreItemWithIcon:imageName highIcon:nil target:self action:@selector(tapMoreNavRightBtn:) tag:itemTag];
            item.tag = itemTag;
            [itemArray addObject:item];
        }];
        self.navigationItem.rightBarButtonItems = itemArray;
    }
    
    #pragma mark - [ 设置导航按钮点击事件 ]
    #pragma mark 点击左按钮
    - (void)tapNavLeftBtn:(UIButton *)sender {
        if ((self.NavLeftImage && self.NavLeftImage.length > 0) ||
            (self.NavLeftImageArray && self.NavLeftImageArray.count > 0))
        {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
    
    #pragma mark 点击右按钮
    - (void)tapNavRightBtn:(UIButton *)sender {
    }
    
    #pragma mark 点击左边其它按钮
    - (void)tapMoreNavLeftBtn:(UIButton *)sender {
    }
    
    #pragma mark 点击右边其它按钮
    - (void)tapMoreNavRightBtn:(UIButton *)sender {
    }
    
    #pragma mark 是否支持右滑返回上一级
    - (void)setIsSlidingReturn:(BOOL)isSlidingReturn {
        _isSlidingReturn = isSlidingReturn;
        //是否支持右滑返回上一级
        self.navigationController.interactivePopGestureRecognizer.enabled = isSlidingReturn;
    }
    
    #pragma mark 触摸事件
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [super touchesBegan:touches withEvent:event];
        [self.view endEditing:YES];
    }
    
    #pragma mark 内存管理
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    #pragma mark - [ 公共的一些方法 ]
    #pragma mark 通过颜色来生成一个纯色图片
    - (UIImage *)imageFromColor:(UIColor *)color rectSize:(CGRect)Rect {
        UIGraphicsBeginImageContext(Rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, Rect);
        UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return img;
    }
    
    #pragma mark 创建自定义UIBarButtonItem
    - (UIBarButtonItem *)itemWithIcon:(NSString *)icon highIcon:(NSString *)highIcon target:(id)target action:(SEL)action {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        //[button setBackgroundImage:[UIImage imageNamed:icon] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:icon] forState:UIControlStateNormal];
        if (highIcon && highIcon.length > 0) {
            //[button setBackgroundImage:[UIImage imageNamed:highIcon] forState:UIControlStateHighlighted];
            [button setImage:[UIImage imageNamed:highIcon] forState:UIControlStateHighlighted];
        }
        
        //button.frame = (CGRect){CGPointZero, button.currentBackgroundImage.size};
        button.frame = CGRectMake(0, 0, 30, 40);
        [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
        button.tag = 1;
        
        UIView *view = [[UIView alloc] init];
        view.frame = button.bounds;
        view.backgroundColor = [UIColor clearColor];
        [view addSubview:button];
        return [[UIBarButtonItem alloc] initWithCustomView:view];
    }
    
    #pragma mark 创建多个自定义UIBarButtonItem
    - (UIBarButtonItem *)moreItemWithIcon:(NSString *)icon highIcon:(NSString *)highIcon target:(id)target action:(SEL)action tag:(NSInteger)tag {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:icon] forState:UIControlStateNormal];
        if (highIcon && highIcon.length > 0) {
            [button setBackgroundImage:[UIImage imageNamed:highIcon] forState:UIControlStateHighlighted];
        }
        button.tag = tag;
        button.frame = (CGRect){CGPointZero, button.currentBackgroundImage.size};
        [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    
        UIView *view = [[UIView alloc] init];
        view.frame = button.bounds;
        view.backgroundColor = [UIColor clearColor];
        [view addSubview:button];
        return [[UIBarButtonItem alloc] initWithCustomView:view];
    }
    
    - (void)presentBottom:(BaseViewController *)bottomVC completion:(void (^)(void))completion {
        self.presentHeight = bottomVC.presentHeight;
        bottomVC.modalPresentationStyle = UIModalPresentationCustom;
        bottomVC.transitioningDelegate = self;
        [self presentViewController:bottomVC animated:YES completion:^{
            if (completion) {
                completion();
            }
        }];
    }
    
    - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source {
        self.presentCtrl = [[BottomPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
        self.presentCtrl.presentHeight = self.presentHeight;
        return self.presentCtrl;
    }
    
    @end
    

    在其中我集成了底部弹窗通用模板类BottomPresentationController,可以在任意继承BaseViewController的视图类中方便的调用弹窗模块。

    BottomPresentationController.h文件如下:

    #import <UIKit/UIKit.h>
    
    @interface BottomPresentationController : UIPresentationController
    
    @property (strong, nonatomic) UIView  *maskView;
    @property (assign, nonatomic) CGFloat presentHeight;
    
    @end
    

    BottomPresentationController.m文件如下:

    #import "BottomPresentationController.h"
    
    @implementation BottomPresentationController
    
    - (id)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController {
        if (self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController]) {
            presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
        }
        return self;
    }
    
    - (void)presentationTransitionWillBegin {
        self.maskView = [[UIView alloc] initWithFrame:self.containerView.bounds];
        self.maskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.65f];
        self.maskView.alpha = 0.0;
        [self.containerView addSubview:self.maskView];
        
        [UIView animateWithDuration:0.5 animations:^{
            self.maskView.alpha = 1.0;
        } completion:^(BOOL finished) {
            [self.maskView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(maskViewTapped:)]];
        }];
    }
    
    - (void)maskViewTapped:(UITapGestureRecognizer *)sender {
        [self.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
    }
    
    - (void)presentationTransitionDidEnd:(BOOL)completed {
        if (!completed) {
            self.maskView = nil;
        }
    }
    
    - (void)dismissalTransitionWillBegin {
        [UIView animateWithDuration:0.5 animations:^{
            self.maskView.alpha = 0.f;
        }];
    }
    
    - (void)dismissalTransitionDidEnd:(BOOL)completed {
        if (completed == YES) {
            [self.maskView removeFromSuperview];
            self.maskView = nil;
        }
    }
    
    - (CGRect)frameOfPresentedViewInContainerView {
        CGRect containerViewBounds = self.containerView.bounds;
        containerViewBounds.origin.y = containerViewBounds.size.height - self.presentHeight;
        containerViewBounds.size.height = self.presentHeight;
        return containerViewBounds;
    }
    
    - (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container {
        [super preferredContentSizeDidChangeForChildContentContainer:container];
        if (container == self.presentedViewController) {
            [self.containerView setNeedsLayout];
        }
    }
    
    - (void)containerViewWillLayoutSubviews {
        [super containerViewWillLayoutSubviews];
        self.maskView.frame = self.containerView.bounds;
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:iOS开发丨使用BaseViewController作为项目视图

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