在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