细细说来,从学iOS到现在也已两年有余,经手的项目也有几个了,都没好好总结些什么。有些东西在忙的时候你会想到你还有些东西没总结,想去总结一下,可这个时候没时间,待等你空闲下来能去好好做你想做的事的时候你又不想费劲思考。匆匆忙忙,慌里慌张!
今天下雨,早上起的早,但上班晚,以至于上班迟到,我还能说些什么?不过这不是重点,重点今天打开CSDN发现挺久没有更新过,也着实不知道改写些什么东西,索性今天就想到哪儿写到哪儿吧!以下只是我个人所了解,如有失望,请轻虐。
从AppDelegate开始吧,我们进入项目第一个要走的就是
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
在这里面如果我们什么都不写,项目运行直接默认进入ViewController,但一般我们做的项目在这里我们都会给rootViewController重新赋值,这个时候如果我们直接运行,有时候会直接崩掉,这时我们要在Info.plist中将
Main storyboard file base name
给去掉,这样的话就会正常显示了。当然这些都是最基础的,一般我们会在这里面设置NavgationController和TabBarController至于让谁当rootViewController看项目需求吧,具体的我就实现了,之前的博客也写过。要是这还满足不了你,没关系继续往下看。
一般来说现在的项目功能会越来越多,而写在控制器中的代码量也越来越大,是我们在修改的时候根本就不想去看这些又臭又长的东西,怎么办呢?我们将部分东西提取出来,把它单独放在一个类中,然后在你想用的地方单独调用。那在AppDelegate中怎么弄呢?很简单我们直接command+n创建Objective-C File,File命名为你能一眼能知道是存放什么功能的名字例如:AppService,File Type:Category ,Class:AppDelegate这样就创建出一个可以承担部分AppDelegate功能的拓展类了,当然在AppDelegate中你要将它引入,在你的AppDelegate+AppService.h中写上你所写的方法名就可以直接在AppDelegate中调用了。方便又快捷赶快试试吧。
另外再说一下,在上一步新建File的时候你如果选的是Extenison的话你可以直接在你想要调用的时候引入,这样你所想要的某个控件或者其它就自然会有你所声明的属性和方法了。
千万不要小看了新建的这个类,你可以在这里面写任何AppDelegate中所包含的方法。例如:你可以写个类里面专门存放有关环信的所有东西,将环信所要实现的方法全放在这里面然后只用一个方法,将环信初始化,在AppDelegate中调用就OK啦。
如果这篇文章只写这么多感觉内容有点缺乏,那再加点。
另外我们说什么呢?就说ViewController吧。一般我们所用的框架都是MVC模式。model负责模型的创建,逻辑赋值等一系列的功能。View负责图像的展示,一个项目好不好看全看这里面的设置。另一个就是Controller了,Controller将View、Model全部串联起来,将需要传递的数据利用Model传递,接受内容反馈等等一系列复杂的功能,这样我们的Controller越到后面就越大,大到看到就想吐,怎么办呢?这里其实我们有好几种办法,我先说比较简单的。
我们先创建一个ViewController然后将一些基本的设置放在里面,之后创建的Controller全部继承自这个VieController,这样就省下了大把的空间,另外的在加载的时候会先加载ViewController里面的东西等加载完成后再加载你所创建的继承自ViewController的类,这样你想改里面的某个东西,可以直接重新赋值就ok了。干说的话好像有点不太形象,直接放例子吧:
RootViewController.h
#import <UIKit/UIKit.h>
#import <MJRefresh.h>
#import "UIViewController+AlertViewAndActionSheet.h"
/**
VC 基类
*/
@interface RootViewController : UIViewController
/**
* 修改状态栏颜色
*/
@property (nonatomic, assign) UIStatusBarStyle StatusBarStyle;
@property (nonatomic, strong) UITableView * tableView;
@property (nonatomic, strong) UICollectionView * collectionView;
/**
* 显示没有数据页面
*/
-(void)showNoDataImage;
/**
* 移除无数据页面
*/
-(void)removeNoDataImage;
/**
* 加载视图
*/
- (void)showLoadingAnimation;
/**
* 停止加载
*/
- (void)stopLoadingAnimation;
/**
* 是否显示返回按钮,默认情况是YES
*/
@property (nonatomic, assign) BOOL isShowLiftBack;
/**
是否隐藏导航栏
*/
@property (nonatomic, assign) BOOL isHidenNaviBar;
/**
导航栏添加文本按钮
@param titles 文本数组
@param isLeft 是否是左边 非左即右
@param target 目标
@param action 点击方法
@param tags tags数组 回调区分用
*/
- (void)addNavigationItemWithTitles:(NSArray *)titles isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags;
/**
导航栏添加图标按钮
@param imageNames 图标数组
@param isLeft 是否是左边 非左即右
@param target 目标
@param action 点击方法
@param tags tags数组 回调区分用
*/
- (void)addNavigationItemWithImageNames:(NSArray *)imageNames isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags;
/**
* 默认返回按钮的点击事件,默认是返回,子类可重写
*/
- (void)backBtnClicked;
//取消网络请求
- (void)cancelRequest;
@end
RootViewController.m
#import "RootViewController.h"
@interface RootViewController ()
@property (nonatomic,strong) UIImageView* noDataView;
@end
@implementation RootViewController
- (UIStatusBarStyle)preferredStatusBarStyle{
return _StatusBarStyle;
}
//动态更新状态栏颜色
-(void)setStatusBarStyle:(UIStatusBarStyle)StatusBarStyle{
_StatusBarStyle=StatusBarStyle;
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =KWhiteColor;
//是否显示返回按钮
self.isShowLiftBack = YES;
//默认导航栏样式:黑字
self.StatusBarStyle = UIStatusBarStyleLightContent;
self.automaticallyAdjustsScrollViewInsets = NO;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication].keyWindow endEditing:YES];
}
- (void)showLoadingAnimation
{
}
- (void)stopLoadingAnimation
{
}
-(void)showNoDataImage
{
_noDataView=[[UIImageView alloc] init];
[_noDataView setImage:[UIImage imageNamed:@"generl_nodata"]];
[self.view.subviews enumerateObjectsUsingBlock:^(UITableView* obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UITableView class]]) {
[_noDataView setFrame:CGRectMake(0, 0,obj.frame.size.width, obj.frame.size.height)];
[obj addSubview:_noDataView];
}
}];
}
-(void)removeNoDataImage{
if (_noDataView) {
[_noDataView removeFromSuperview];
_noDataView = nil;
}
}
/**
* 懒加载UITableView
*
* @return UITableView
*/
- (UITableView *)tableView
{
if (_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight - kTopHeight -kTabBarHeight) style:UITableViewStylePlain];
_tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
//头部刷新
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefreshing)];
header.automaticallyChangeAlpha = YES;
header.lastUpdatedTimeLabel.hidden = YES;
_tableView.mj_header = header;
//底部刷新
_tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRefreshing)];
// _tableView.contentInset = UIEdgeInsetsMake(0, 0, 30, 0);
// _tableView.mj_footer.ignoredScrollViewContentInsetBottom = 30;
_tableView.backgroundColor=CViewBgColor;
_tableView.scrollsToTop = YES;
_tableView.tableFooterView = [[UIView alloc] init];
}
return _tableView;
}
/**
* 懒加载collectionView
*
* @return collectionView
*/
- (UICollectionView *)collectionView
{
if (_collectionView == nil) {
UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth , KScreenHeight - kTopHeight - kTabBarHeight) collectionViewLayout:flow];
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefreshing)];
header.automaticallyChangeAlpha = YES;
header.lastUpdatedTimeLabel.hidden = YES;
header.stateLabel.hidden = YES;
_collectionView.mj_header = header;
//底部刷新
_collectionView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRefreshing)];
//#ifdef kiOS11Before
//
//#else
// _collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
// _collectionView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
// _collectionView.scrollIndicatorInsets = _collectionView.contentInset;
//#endif
_collectionView.backgroundColor=CViewBgColor;
_collectionView.scrollsToTop = YES;
}
return _collectionView;
}
-(void)headerRefreshing{
}
-(void)footerRefreshing{
}
/**
* 是否显示返回按钮
*/
- (void) setIsShowLiftBack:(BOOL)isShowLiftBack
{
_isShowLiftBack = isShowLiftBack;
NSInteger VCCount = self.navigationController.viewControllers.count;
//下面判断的意义是 当VC所在的导航控制器中的VC个数大于1 或者 是present出来的VC时,才展示返回按钮,其他情况不展示
if (isShowLiftBack && ( VCCount > 1 || self.navigationController.presentingViewController != nil)) {
[self addNavigationItemWithImageNames:@[@"back_icon"] isLeft:YES target:self action:@selector(backBtnClicked) tags:nil];
} else {
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem * NULLBar=[[UIBarButtonItem alloc]initWithCustomView:[UIView new]];
self.navigationItem.leftBarButtonItem = NULLBar;
}
}
- (void)backBtnClicked
{
if (self.presentingViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark ————— 导航栏 添加图片按钮 —————
/**
导航栏添加图标按钮
@param imageNames 图标数组
@param isLeft 是否是左边 非左即右
@param target 目标
@param action 点击方法
@param tags tags数组 回调区分用
*/
- (void)addNavigationItemWithImageNames:(NSArray *)imageNames isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags
{
NSMutableArray * items = [[NSMutableArray alloc] init];
//调整按钮位置
// UIBarButtonItem* spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
// //将宽度设为负值
// spaceItem.width= -5;
// [items addObject:spaceItem];
NSInteger i = 0;
for (NSString * imageName in imageNames) {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
btn.frame = CGRectMake(0, 0, 30, 30);
[btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
if (isLeft) {
[btn setContentEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 10)];
}else{
[btn setContentEdgeInsets:UIEdgeInsetsMake(0, 10, 0, -10)];
}
btn.tag = [tags[i++] integerValue];
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:btn];
[items addObject:item];
}
if (isLeft) {
self.navigationItem.leftBarButtonItems = items;
} else {
self.navigationItem.rightBarButtonItems = items;
}
}
#pragma mark ————— 导航栏 添加文字按钮 —————
- (NSMutableArray<UIButton *> *)addNavigationItemWithTitles:(NSArray *)titles isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags
{
NSMutableArray * items = [[NSMutableArray alloc] init];
//调整按钮位置
// UIBarButtonItem* spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
// //将宽度设为负值
// spaceItem.width= -5;
// [items addObject:spaceItem];
NSMutableArray * buttonArray = [NSMutableArray array];
NSInteger i = 0;
for (NSString * title in titles) {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 0, 30, 30);
[btn setTitle:title forState:UIControlStateNormal];
[btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
btn.titleLabel.font = SYSTEMFONT(16);
[btn setTitleColor:KWhiteColor forState:UIControlStateNormal];
btn.tag = [tags[i++] integerValue];
[btn sizeToFit];
//设置偏移
if (isLeft) {
[btn setContentEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 10)];
}else{
[btn setContentEdgeInsets:UIEdgeInsetsMake(0, 10, 0, -10)];
}
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:btn];
[items addObject:item];
[buttonArray addObject:btn];
}
if (isLeft) {
self.navigationItem.leftBarButtonItems = items;
} else {
self.navigationItem.rightBarButtonItems = items;
}
return buttonArray;
}
//取消请求
- (void)cancelRequest
{
}
- (void)dealloc
{
[self cancelRequest];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - 屏幕旋转
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
//当前支持的旋转类型
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate
{
// 是否支持旋转
return NO;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
// 默认进去类型
return UIInterfaceOrientationPortrait;
}
@end
之后的所有Controller都继承这个类,当你用tableView的时候,将tableView加载上去,用collectionView的时候将collectionView加载上去,会自动有上拉下拉刷新,直接调用方法就完成了,是不是省去一大堆的麻烦。
未完待续。。。