iOS项目框架,开发流程总结

插眼传送 淘劵吧

做外包很长时间,搭项目框架搭吐血,花了半个小时搭建个基本项目框架,一劳永逸。

在本项目你能得到什么

  • 基类控制器(带刷新,占位图)
  • 常用第三方收录其中
  • 工具类封装(网络,管理)
  • 类别扩展,常用控件扩展
  • 常用宏定义 (常量,函数)

简易总结了下,APP开发流程

屏幕快照 2017-09-18 下午2.24.51.png

BaseViewController

BaseViewController 主要对导航条的处理,自定义,标题,整体返回功能......

#import <UIKit/UIKit.h>

@interface BaseViewController : UIViewController

@property (nonatomic,strong)UINavigationBar *navigationBar;

/**
 控制器title
 */
@property (nonatomic,strong)NSString *navigationTitle;

/**
 设置LeftBarItem

 @param title 标题/ 非必填
 */
- (void)setLeftBarItemWithTitle:(NSString *)title;

/**
 设置RightBarItem

 @param icon 图片
 @param action 响应方法
 */
- (void)setRightBarButtonItemWithIcon:(NSString *)icon Action:(SEL)action;

/**
  设置RightBarItem

 @param title 标题
 @param action 响应事件
 */
- (void)setRightBarButtonItemWithTitle:(NSString *)title Action:(SEL)action;

/**
   设置RightBarItems

 @param icon1 图标1
 @param action1 事件1
 @param icon2 图片2
 @param action2 事件2
 */
- (void)setRightBarButtonItemWithIcon1:(NSString *)icon1 Action1:(SEL)action1 AndIcon2:(NSString *)icon2 Action:(SEL)action2;

@end

#import "BaseViewController.h"
#import "UIButton+Extension.h"

@interface BaseViewController ()

/**
 注意:整体返回思路-> 
 1,隐藏系统的NavigationBar;
 2,自定义navigationBar 添加在Controller.View 上 坐标是:(0,0,屏幕宽,64)
 3,在表视图中(继承与BaseCollectionViewController,BaseTableViewController)的控制器中,表视图的坐标(0,0,屏幕宽,屏幕高),通过修改 contentInset属性调整;
 4,对于不是表视图控制器,其子控件坐标从(0,64)开始计算
 
 */
@property (nonatomic,strong)UINavigationItem *navItem;

@property (nonatomic,strong)UILabel *titleLabel;

@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.automaticallyAdjustsScrollViewInsets = NO;
    self.edgesForExtendedLayout = UIRectEdgeBottom;
    
    [self createNavigationBar];
}
#pragma mark - 导航条
- (void)createNavigationBar
{
    // 创建一个导航栏
    self.navigationBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 64)];
    // 导航栏背景颜色
    self.navigationBar.barTintColor = [UIColor returnColorWithHexString:@"#FFFFFF"];
    // 创建导航栏组件
      self.navItem =[[UINavigationItem alloc]init];
    // 自定义导航栏的title,用UILabel实现
    _titleLabel = [UILabel getLabelWithFontSize:18 AndTextColer:@"#333333" AndBackGroundColor:nil];
    _titleLabel.frame = CGRectMake(0, 0, 100, 44);
    _titleLabel.textAlignment = NSTextAlignmentCenter;
   self.navItem.titleView = _titleLabel;
    [self.navigationBar pushNavigationItem:self.navItem animated:false];
    [self.view addSubview:self.navigationBar];
}
#pragma mark - 标题
- (void)setNavigationTitle:(NSString *)navigationTitle
{
    _navigationTitle = navigationTitle;
    self.titleLabel.text = navigationTitle;
}
#pragma mark - LeftBarItem
- (void)setLeftBarItemWithTitle:(NSString *)title
{
    UIButton *button = [UIButton getButtonWithFontSize:15 AndTextColor:@"#666666" AndBackGroundColor:nil];
    [button setButtonNormalImage:@"leftarrow" SelectImage:nil];
    [button setTitle:title forState:UIControlStateNormal];
    button.contentHorizontalAlignment = NSTextAlignmentRight;
    [button addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
    CGFloat titleWith = StringWidth(title, 18, 18);
    if (title == nil || title.length == 0) {
        button.frame = CGRectMake(0, 0, 44, 44);
        button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 44 - 8);
    }else{
        button.frame = CGRectMake(0, 0, titleWith + 10, 44);
        button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, titleWith - 8);
    }
    // 调整LeftButton 边距的问题
    UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]   initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace   target:nil action:nil];
    negativeSpacer.width = -5;
    UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:button];
    self.navItem.leftBarButtonItems = @[negativeSpacer,leftBarButton];
}
#pragma mark - RightBarItem
- (void)setRightBarButtonItemWithIcon:(NSString *)icon Action:(SEL)action
{
    if (icon != nil || icon.length != 0) {
        [self setRightBarItemWithImage:icon title:nil action:action];
    }
}
- (void)setRightBarButtonItemWithTitle:(NSString *)title Action:(SEL)action
{
    if (title != nil || title.length != 0) {
        [self setRightBarItemWithImage:nil title:title action:action];
    }
}
- (void)setRightBarItemWithImage:(NSString *)icom title:(NSString *)title action:(SEL)action
{
    UIButton *button = [UIButton getButtonWithFontSize:15 AndTextColor:@"#666666" AndBackGroundColor:nil];
    [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    if (icom == nil || icom.length == 0) {
        CGFloat titleWith = StringWidth(title, 18, 18);
        button.frame = CGRectMake(0, 0, titleWith, 44);
        [button setTitle:title forState:UIControlStateNormal];
    }else{
        button.frame = CGRectMake(0, 0, 44, 44);
        [button setImage:[UIImage imageNamed:icom] forState:UIControlStateNormal];
    }
    // 调整LeftButton 边距的问题
    UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]   initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace   target:nil action:nil];
    negativeSpacer.width = -5;
    UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc]initWithCustomView:button];
    self.navItem.rightBarButtonItems = @[negativeSpacer,rightBarButton];
}
- (void)setRightBarButtonItemWithIcon1:(NSString *)icon1 Action1:(SEL)action1 AndIcon2:(NSString *)icon2 Action:(SEL)action2
{
    UIBarButtonItem *rightBarButton1 = [[UIBarButtonItem alloc]initWithImage:[[UIImage imageNamed:icon1] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]style:UIBarButtonItemStylePlain target:self action:action1];
    UIBarButtonItem *rightBarButton2 = [[UIBarButtonItem alloc]initWithImage:[[UIImage imageNamed:icon2] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]style:UIBarButtonItemStylePlain target:self action:action2];
    self.navItem.rightBarButtonItems = @[rightBarButton1,rightBarButton2];
}

- (void)backAction
{
    [self.navigationController popViewControllerAnimated:YES];
}

@end

BaseTableViewController

主要对最常用的TableViewController处理,集成刷新,占位图。。。

#import "BaseViewController.h"

@interface BaseTableViewController : BaseViewController

@property (nonatomic,strong)UITableView *mainTableView;// 表格
@property (nonatomic,strong)NSMutableArray *dataArray;// 数据源
@property (nonatomic,assign)NSInteger pageCount;// 页数
@property (nonatomic,assign)NSInteger number;//每页条数

#pragma mark - 上拉加载更多,下拉刷新
/**
 去除上下拉加载
 */
- (void)removedRefreshing;
/**
 隐藏加载更多
 */
- (void)hideLoadMoreRefreshing;
/**
 结束刷新
 */
- (void)endRefreshing;
/**
 刷新表格
 */
- (void)refreshData;

@end
#import "BaseTableViewController.h"
#import "UIScrollView+EmptyDataSet.h"
#import "MJRefresh.h"


@interface BaseTableViewController ()<UITableViewDelegate,UITableViewDataSource,DZNEmptyDataSetSource,DZNEmptyDataSetDelegate>
@property (nonatomic, getter=isLoading)BOOL loading;

@end

@implementation BaseTableViewController
- (void)setLoading:(BOOL)loading
{
    if (self.loading == loading) {
        return;
    }
    _loading = loading;
    [self.mainTableView reloadEmptyDataSet];
}
- (NSMutableArray *)dataArray
{
    if (_dataArray == nil) {
        _dataArray = [[NSMutableArray alloc]init];
    }
    return _dataArray;
}
#pragma mark - 懒加载
- (UITableView *)mainTableView
{
    if (!_mainTableView) {
        _mainTableView  = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, K_Screen_width, K_Screen_height) style:UITableViewStyleGrouped];
        _mainTableView.delegate = self;
        _mainTableView.dataSource = self;
        _mainTableView.scrollsToTop = YES;
        _mainTableView.emptyDataSetSource = self;
        _mainTableView.emptyDataSetDelegate = self;
        _mainTableView.showsVerticalScrollIndicator = NO;
        _mainTableView.showsHorizontalScrollIndicator = NO;
        _mainTableView.backgroundColor = [UIColor whiteColor];
        _mainTableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
        _mainTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(reloadNewData)];
        _mainTableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(reloadMoreData)];
    }
    return _mainTableView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    _pageCount = 1;
    _number = 10;
    self.dataArray = @[@""].mutableCopy;// 防止刚进入页面时显示出占位图
    [self.view insertSubview:self.mainTableView belowSubview:self.navigationBar];
    [self requestData];
}
#pragma mark - 网络请求 (子类重写)
- (void)requestData
{
    [self endRefreshing];
}
#pragma mark - 上下拉获取数据
- (void)reloadNewData
{
    _pageCount = 1;
    [self requestData];
}
- (void)reloadMoreData
{
    _pageCount ++;
    [self requestData];
}
- (void)removedRefreshing
{
    self.mainTableView.mj_header = nil;
    self.mainTableView.mj_footer = nil;
}
- (void)endRefreshing
{
    [self.mainTableView.mj_header endRefreshing];
    [self.mainTableView.mj_footer endRefreshing];
}
- (void)hideLoadMoreRefreshing
{
    self.mainTableView.mj_footer.hidden = YES;
}
- (void)refreshData
{
    [self.mainTableView reloadData];
}
#pragma mark - TableViewDelegate dataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.0001;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 0.0001;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cell_id = @"falg";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%ld分区%ld行",indexPath.section,indexPath.row];
    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}

#pragma mark - DZNEmptyDataSetSource
/**
 *  返回文字详情
 */
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
{
    NSString *text = @"点击图片重新加载";
    NSMutableAttributedString *attribuString = [[NSMutableAttributedString alloc]initWithString:text attributes:nil];
    [attribuString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PF-SC-Regular" size:12] range:[attribuString.string rangeOfString:@"哈哈哈"]];
    return attribuString;
}
/**
 *  调整垂直位置
 */
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
{
    return [UIImage imageNamed:@"zhanwei"];
}
//返回loading的状态
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView
{
    return self.isLoading;
}
- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView
{
    return -64.f;
}
#pragma mark - DZNEmptyDataSetDelegate
/**
 *  空白区域点击事件
 */
- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view
{
    /*
     动画效果
         self.loading = YES;
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
             self.loading = NO;
         });
         [self requestData];
     */
// 刷新
    [self.mainTableView.mj_header beginRefreshing];
}

- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    animation.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0) ];
    animation.duration = 0.25;
    animation.cumulative = YES;
    animation.repeatCount = MAXFLOAT;
    return animation;
}

@end

具体看demo,就不一一举栗子了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,376评论 25 707
  • 我的好朋友和我喜欢的男生在一起了。 晴天霹雳。五一假期结束,睡足了觉醒来,刷微博看到T的最新动态。一句“H先森,余...
    苏叶凉阅读 767评论 3 6
  • 我喜欢优雅和高效的代码,代码逻辑应当直截了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善...
    小刘and12345阅读 218评论 0 0
  • 又到了夜深人静的时候了,室友们也都一一入睡,这个时候,仿佛整个世界都留给了我一人。结束了一天的喧嚣,留下的寂静,让...
    大小刘阅读 280评论 0 0