還在為每個視圖控制器都要自定義導航欄按鈕而煩躁嗎雷恃?還在為每個視圖控制器的列表都要添加一遍上拉刷新下拉加載而焦心嗎?還在為每個列表添加空白提示而煩惱嗎抒巢?不要怕胎撇,你需要一個基類介粘,一個救你于水火的VC的基類!
當你看到一個VC中幾千行代碼的時候你是絕望的创坞,崩潰的碗短!那些每個界面都要寫的代碼就是冗余代碼,我們完全可以在vc的基類中來寫這些代碼题涨,只要vc繼承基類vc偎谁,那么我們只需要一句代碼就可以完成創(chuàng)建導航左右按鈕,為列表添加上拉上推事件等等繁瑣而相同的事情纲堵!既能優(yōu)化界面巡雨,又能讓你的代碼略微提升那么一點逼格,何樂而不為呢席函,是吧老鐵~ 好了铐望,廢話結(jié)束,進入正題茂附!
首先在返回按鈕跟設(shè)置的普通返回按鈕不同的時候正蛙,或者導航欄右按鈕需要有點擊事件的時候,一般我們會選擇自定義導航欄左右按鈕营曼。當一個APP有多個界面需要自定義左右按鈕的時候乒验,這些代碼充斥在多個視圖控制器中會顯得雜亂和冗余,這時候我們就可以在基類VC中這么寫蒂阱,.h文件
typedef void(^navigationBtnBlock)(UIButton *navBtn);
@interface BaseViewController : UIViewController
/** navigationBar item click */
@property (nonatomic, copy)navigationBtnBlock navBtnAction;
@end
.m文件
#pragma mark ------- set nav left item
-(void)createBackBtnWithImageName:(NSString *)imageName{
UIButton *btn_back = [UIButton buttonWithType:UIButtonTypeCustom];
btn_back.frame = CGRectMake(0, 0, 40, 30);
btn_back.contentEdgeInsets = UIEdgeInsetsMake(0, -2, 0, 0);
btn_back.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[btn_back setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
btn_back.tag = 9;
//保證所有touch事件button的highlighted屬性為NO,即可去除高亮效果
[btn_back addTarget:self action:@selector(preventFlicker:) forControlEvents:UIControlEventAllTouchEvents];
[btn_back addTarget:self action:@selector(popToLastVC:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithCustomView:btn_back];
self.navigationItem.leftBarButtonItem = leftItem;
}
-(void)popToLastVC:(UIButton *)sender{
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count == 0) {
return;
}
if (self.navBtnAction) {//如果vc中調(diào)用了block回調(diào)就走自己的回調(diào)
self.navBtnAction(sender);
}else{//如果vc中沒有調(diào)用block回調(diào)锻全,直接返回到到上級頁面
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark ------- wipe out button highlight
-(void)preventFlicker:(UIButton *)sender{
sender.highlighted = NO;
}
#pragma mark ------- set nav right item
-(void)createNavRightBtnWithImageName:(NSString *)imageName{
UIButton *btn_right = [UIButton buttonWithType:UIButtonTypeCustom];
btn_right.frame = CGRectMake(0, 0, 40, 30);
btn_right.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 2);
btn_right.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
[btn_right setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
btn_right.tag = 10;
//保證所有touch事件button的highlighted屬性為NO,即可去除高亮效果
[btn_right addTarget:self action:@selector(preventFlicker:) forControlEvents:UIControlEventAllTouchEvents];
[btn_right addTarget:self action:@selector(rightBtnClick:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithCustomView:btn_right];
self.navigationItem.rightBarButtonItem = rightItem;
}
-(void)rightBtnClick:(UIButton *)sender{
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count == 0) {
return;
}
if (self.navBtnAction) {//如果vc中調(diào)用了block回調(diào)就走自己的回調(diào)
self.navBtnAction(sender);
}else{//如果vc中沒有調(diào)用block回調(diào)狂塘,直接返回到到上級頁面
[self.navigationController popViewControllerAnimated:YES];
}
}
在繼承基類的VC中我們可以這樣調(diào)用
[self createBackBtnWithImageName:@"圖片名字"];
//如果不設(shè)置這個block回到,點擊返回按鈕就會直接返回上一級界面
self.navBtnAction = ^(UIButton * _Nonnull navBtn) {
//這里可以通過按鈕的tag值來判斷點擊的是按鈕
};
列表是大部分APP都會頻繁使用的控件鳄厌,但是為tableView設(shè)置上推和下拉的事件卻是比較繁瑣的荞胡,我們可以在基類中這樣來寫,.h文件代碼如下:
typedef void(^tableViewRefreshBlock)(NSInteger pageNum);
typedef void(^navigationBtnBlock)(UIButton *navBtn);
@interface BaseViewController : UIViewController
/** tableView pull or push action */
@property (nonatomic, copy)tableViewRefreshBlock tableViewRefresh;
/** add tableview pull and push action */
-(void)addTableHeaderRefresh:(BOOL)headerRefresh tableFooterRefresh:(BOOL)footerRefresh;
@end
.m文件代碼
#pragma mark ------- tableView pull and push action
-(void)addTableHeaderRefresh:(BOOL)headerRefresh tableFooterRefresh:(BOOL)footerRefresh{
if (headerRefresh) {
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(reloadData)];
header.lastUpdatedTimeLabel.hidden = YES;
[header setTitle:@"拼命加載中..." forState:MJRefreshStateRefreshing];
[header setTitle:@"下拉刷新數(shù)據(jù)~" forState:MJRefreshStateIdle];
self.tableView.mj_header = header;
}
if (footerRefresh) {
MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
[footer setTitle:@"我是有底線的~" forState:MJRefreshStateNoMoreData];
[footer setTitle:@"拼命加載中..." forState:MJRefreshStateRefreshing];
[footer setTitle:@"上拉更多精彩~" forState:MJRefreshStateIdle];
footer.stateLabel.textColor = [UIColor lightGrayColor];
self.tableView.mj_footer = footer;
}
}
-(void)reloadData{
_pageNum = 1;
if (self.tableViewRefresh) {
self.tableViewRefresh(_pageNum);
}
}
-(void)loadMoreData{
_pageNum ++;
if (self.tableViewRefresh) {
self.tableViewRefresh(_pageNum);
}
}
-(void)tableViewEndRefresh{
[self.tableView.mj_header endRefreshing];
[self.tableView.mj_footer endRefreshing];
}
在繼承基類的VC中我們可以這樣調(diào)用
//設(shè)置為YES就添加事件了嚎,為NO則不添加事件
[self addTableHeaderRefresh:YES tableFooterRefresh:YES];
self.tableViewRefresh = ^(NSInteger pageNum) {
//回調(diào)回來當前的pageNum
//這里可以進行數(shù)據(jù)請求
};
還有一些其他的方法泪漂,提示框,空白頁等等諸如此類都已在基類中設(shè)置新思,我總結(jié)了一下分享給大家,一起學習~
typedef void(^navigationBtnBlock)(UIButton *navBtn);
typedef void(^tableViewRefreshBlock)(NSInteger pageNum);
@interface BaseViewController : UIViewController
/** navigationBar item click */
@property (nonatomic, copy)navigationBtnBlock navBtnAction;
/** tableView pull or push action */
@property (nonatomic, copy)tableViewRefreshBlock tableViewRefresh;
/** tableView */
@property (nonatomic, strong)UITableView *tableView;
/** tableView current page */
@property (nonatomic, assign)NSInteger pageNum;
/** set custom navigation leftItem */
-(void)createBackBtnWithImageName:(NSString *)imageName;
/** set navigationbar backgroundColor */
-(void)setNavigationBarBackgroundImageWithColor:(UIColor *)color;
/** set custom navigation rightItem */
-(void)createNavRightBtnWithImageName:(NSString *)imageName;
/** show custom aleartView */
-(void)showMessageBottomWithText:(NSString *)text;
/** add tableview pull and push action */
-(void)addTableHeaderRefresh:(BOOL)headerRefresh tableFooterRefresh:(BOOL)footerRefresh;
/** show custom hud */
-(void)showCustomMessageViewWithText:(NSString *)text;
/** hide custom hud */
-(void)hiddenCustomMessageView;
/** show custom activeIndicator*/
-(void)showCustomActiveIndicator;
/**hide custom activeIndicator*/
-(void)hiddenCustomActiveIndicator;
@end
.m文件
@interface BaseViewController (){
UIImageView *navBarHairlineImageView;
UIActivityIndicatorView *_activityIndicator;
}
@end
@implementation BaseViewController
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
navBarHairlineImageView.hidden = YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//prevent view move down
self.automaticallyAdjustsScrollViewInsets = NO;
//set view backgroundColor
self.view.backgroundColor = [UIColor whiteColor];
//set nav backgroundColor
[self setNavigationBarBackgroundImageWithColor:[UIColor whiteColor]];
//wipe out the black line under the navigation bar
UINavigationBar *navigationBar = self.navigationController.navigationBar;
navBarHairlineImageView = [self slnFindHairlineImageViewUnder:navigationBar];
}
#pragma mark ------- set nav left item
-(void)createBackBtnWithImageName:(NSString *)imageName{
UIButton *btn_back = [UIButton buttonWithType:UIButtonTypeCustom];
btn_back.frame = CGRectMake(0, 0, 40, 30);
btn_back.contentEdgeInsets = UIEdgeInsetsMake(0, -2, 0, 0);
btn_back.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[btn_back setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
btn_back.tag = 9;
//保證所有touch事件button的highlighted屬性為NO,即可去除高亮效果
[btn_back addTarget:self action:@selector(preventFlicker:) forControlEvents:UIControlEventAllTouchEvents];
[btn_back addTarget:self action:@selector(popToLastVC:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithCustomView:btn_back];
self.navigationItem.leftBarButtonItem = leftItem;
}
-(void)popToLastVC:(UIButton *)sender{
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count == 0) {
return;
}
if (self.navBtnAction) {//如果vc中調(diào)用了block回調(diào)就走自己的回調(diào)
self.navBtnAction(sender);
}else{//如果vc中沒有調(diào)用block回調(diào)窖梁,直接返回到到上級頁面
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark ------- wipe out button highlight
-(void)preventFlicker:(UIButton *)sender{
sender.highlighted = NO;
}
#pragma mark ------- set nav right item
-(void)createNavRightBtnWithImageName:(NSString *)imageName{
UIButton *btn_right = [UIButton buttonWithType:UIButtonTypeCustom];
btn_right.frame = CGRectMake(0, 0, 40, 30);
btn_right.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 2);
btn_right.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
[btn_right setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
btn_right.tag = 10;
//保證所有touch事件button的highlighted屬性為NO,即可去除高亮效果
[btn_right addTarget:self action:@selector(preventFlicker:) forControlEvents:UIControlEventAllTouchEvents];
[btn_right addTarget:self action:@selector(rightBtnClick:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithCustomView:btn_right];
self.navigationItem.rightBarButtonItem = rightItem;
}
-(void)rightBtnClick:(UIButton *)sender{
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count == 0) {
return;
}
if (self.navBtnAction) {//如果vc中調(diào)用了block回調(diào)就走自己的回調(diào)
self.navBtnAction(sender);
}else{//如果vc中沒有調(diào)用block回調(diào)赘风,直接返回到到上級頁面
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark ------- create a image
-(UIImage *)createImageWithView:(UIView *)view{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, 0, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
-(UIView *)getColorViewWithColor:(UIColor *)color{
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, navgationBarH)];
view.backgroundColor = color;
if (CGColorEqualToColor(color.CGColor, [UIColor clearColor].CGColor) || CGColorEqualToColor(color.CGColor, APPColor.CGColor)) {
}else{
view.layer.borderColor = ColorWithRGB(239, 239, 239).CGColor;
view.layer.borderWidth = 0.5;
view.layer.shadowColor=[ColorWithRGB(200, 200, 200) colorWithAlphaComponent:0.8].CGColor;
view.layer.shadowOffset=CGSizeMake(-4,-4);
view.layer.shadowOpacity=0.5;
view.layer.shadowRadius=4;
view.clipsToBounds = false;
}
return view;
}
#pragma mark ------- get nav bottom black line
-(UIImageView *)slnFindHairlineImageViewUnder:(UIView *)view {
if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0){
return (UIImageView *)view;
}
for (UIView *subview in view.subviews) {
UIImageView *imageView = [self slnFindHairlineImageViewUnder:subview];
if (imageView) {
return imageView;
}
}
return nil;
}
#pragma mark ------- set nav background color
-(void)setNavigationBarBackgroundImageWithColor:(UIColor *)color{
[self.navigationController.navigationBar setBackgroundImage:[self createImageWithView:[self getColorViewWithColor:color]] forBarMetrics:UIBarMetricsDefault];
}
#pragma mark ------- show messgae on view of bottom
-(void)showMessageBottomWithText:(NSString *)text{
[CLToast showBottomWithText:NSLocalizedString(text, nil)];
}
#pragma mark ------- tableView pull and push action
-(void)addTableHeaderRefresh:(BOOL)headerRefresh tableFooterRefresh:(BOOL)footerRefresh{
if (headerRefresh) {
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(reloadData)];
header.lastUpdatedTimeLabel.hidden = YES;
[header setTitle:@"拼命加載中..." forState:MJRefreshStateRefreshing];
[header setTitle:@"下拉刷新數(shù)據(jù)~" forState:MJRefreshStateIdle];
self.tableView.mj_header = header;
}
if (footerRefresh) {
MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
[footer setTitle:@"我是有底線的~" forState:MJRefreshStateNoMoreData];
[footer setTitle:@"拼命加載中..." forState:MJRefreshStateRefreshing];
[footer setTitle:@"上拉更多精彩~" forState:MJRefreshStateIdle];
footer.stateLabel.textColor = [UIColor lightGrayColor];
self.tableView.mj_footer = footer;
}
}
-(void)reloadData{
_pageNum = 1;
if (self.tableViewRefresh) {
self.tableViewRefresh(_pageNum);
}
}
-(void)loadMoreData{
_pageNum ++;
if (self.tableViewRefresh) {
self.tableViewRefresh(_pageNum);
}
}
-(void)tableViewEndRefresh{
[self.tableView.mj_header endRefreshing];
[self.tableView.mj_footer endRefreshing];
}
#pragma mark ------- custom hud
-(void)showCustomMessageViewWithText:(NSString *)text{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
//修改樣式夹囚,否則等待框背景色將為半透明
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
//設(shè)置等待框背景色為黑色
hud.bezelView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
//設(shè)置菊花框為白色
[UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]].color = [UIColor whiteColor];
hud.label.text = NSLocalizedString(text, nil);
hud.label.textColor = [UIColor whiteColor];
hud.userInteractionEnabled = YES;
hud.mode = MBProgressHUDModeIndeterminate;
}
-(void)hiddenCustomMessageView{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
#pragma mark ------- custom activeIndicator
-(void)showCustomActiveIndicator{
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self.view addSubview:_activityIndicator];
_activityIndicator.frame = CGRectMake((SCREEN_WIDTH - 99*WidthRatio)/2, (SCREEN_HEIGHT-99*WidthRatio)/2 - (navgationBarH + tabbarH)/2, 99*WidthRatio, 99*WidthRatio);
_activityIndicator.hidesWhenStopped = NO;
[_activityIndicator startAnimating];
}
-(void)hiddenCustomActiveIndicator{
[_activityIndicator stopAnimating];
[_activityIndicator removeFromSuperview];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[[SDImageCache sharedImageCache] clearMemory];//清內(nèi)存
[[SDImageCache sharedImageCache] clearDiskOnCompletion:nil];//清內(nèi)存
// 1.取消正在下載的操作
[[SDWebImageManager sharedManager] cancelAll];
// 2.清除內(nèi)存緩存
[[SDWebImageManager sharedManager].imageCache clearMemory];
}