iOS項(xiàng)目框架,開發(fā)流程總結(jié)

插眼傳送 淘劵吧

做外包很長時間挡闰,搭項(xiàng)目框架搭吐血乒融,花了半個小時搭建個基本項(xiàng)目框架,一勞永逸摄悯。

在本項(xiàng)目你能得到什么

  • 基類控制器(帶刷新赞季,占位圖)
  • 常用第三方收錄其中
  • 工具類封裝(網(wǎng)絡(luò),管理)
  • 類別擴(kuò)展奢驯,常用控件擴(kuò)展
  • 常用宏定義 (常量申钩,函數(shù))

簡易總結(jié)了下,APP開發(fā)流程

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

BaseViewController

BaseViewController 主要對導(dǎo)航條的處理瘪阁,自定義撒遣,標(biāo)題,整體返回功能......

#import <UIKit/UIKit.h>

@interface BaseViewController : UIViewController

@property (nonatomic,strong)UINavigationBar *navigationBar;

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

/**
 設(shè)置LeftBarItem

 @param title 標(biāo)題/ 非必填
 */
- (void)setLeftBarItemWithTitle:(NSString *)title;

/**
 設(shè)置RightBarItem

 @param icon 圖片
 @param action 響應(yīng)方法
 */
- (void)setRightBarButtonItemWithIcon:(NSString *)icon Action:(SEL)action;

/**
  設(shè)置RightBarItem

 @param title 標(biāo)題
 @param action 響應(yīng)事件
 */
- (void)setRightBarButtonItemWithTitle:(NSString *)title Action:(SEL)action;

/**
   設(shè)置RightBarItems

 @param icon1 圖標(biāo)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,隱藏系統(tǒng)的NavigationBar;
 2,自定義navigationBar 添加在Controller.View 上 坐標(biāo)是:(0,0,屏幕寬,64)
 3,在表視圖中(繼承與BaseCollectionViewController管跺,BaseTableViewController)的控制器中义黎,表視圖的坐標(biāo)(0,0豁跑,屏幕寬廉涕,屏幕高),通過修改 contentInset屬性調(diào)整艇拍;
 4狐蜕,對于不是表視圖控制器,其子控件坐標(biāo)從(0卸夕,64)開始計(jì)算
 
 */
@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 - 導(dǎo)航條
- (void)createNavigationBar
{
    // 創(chuàng)建一個導(dǎo)航欄
    self.navigationBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 64)];
    // 導(dǎo)航欄背景顏色
    self.navigationBar.barTintColor = [UIColor returnColorWithHexString:@"#FFFFFF"];
    // 創(chuàng)建導(dǎo)航欄組件
      self.navItem =[[UINavigationItem alloc]init];
    // 自定義導(dǎo)航欄的title馏鹤,用UILabel實(shí)現(xiàn)
    _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 - 標(biāo)題
- (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);
    }
    // 調(diào)整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];
    }
    // 調(diào)整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;// 數(shù)據(jù)源
@property (nonatomic,assign)NSInteger pageCount;// 頁數(shù)
@property (nonatomic,assign)NSInteger number;//每頁條數(shù)

#pragma mark - 上拉加載更多治力,下拉刷新
/**
 去除上下拉加載
 */
- (void)removedRefreshing;
/**
 隱藏加載更多
 */
- (void)hideLoadMoreRefreshing;
/**
 結(jié)束刷新
 */
- (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;// 防止剛進(jìn)入頁面時顯示出占位圖
    [self.view insertSubview:self.mainTableView belowSubview:self.navigationBar];
    [self requestData];
}
#pragma mark - 網(wǎng)絡(luò)請求 (子類重寫)
- (void)requestData
{
    [self endRefreshing];
}
#pragma mark - 上下拉獲取數(shù)據(jù)
- (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分區(qū)%ld行",indexPath.section,indexPath.row];
    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}

#pragma mark - DZNEmptyDataSetSource
/**
 *  返回文字詳情
 */
- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
{
    NSString *text = @"點(diǎn)擊圖片重新加載";
    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;
}
/**
 *  調(diào)整垂直位置
 */
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
{
    return [UIImage imageNamed:@"zhanwei"];
}
//返回loading的狀態(tài)
- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView
{
    return self.isLoading;
}
- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView
{
    return -64.f;
}
#pragma mark - DZNEmptyDataSetDelegate
/**
 *  空白區(qū)域點(diǎn)擊事件
 */
- (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,就不一一舉栗子了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勃黍,一起剝皮案震驚了整個濱河市宵统,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖马澈,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓢省,死亡現(xiàn)場離奇詭異羔飞,居然都是意外死亡楼入,警方通過查閱死者的電腦和手機(jī)衷恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門乳丰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人潮改,你說我怎么就攤上這事热康⊙渡颍” “怎么了凝果?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵祝迂,是天一觀的道長。 經(jīng)常有香客問我器净,道長型雳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任山害,我火速辦了婚禮四啰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粗恢。我一直安慰自己,他們只是感情好欧瘪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布眷射。 她就那樣靜靜地躺著,像睡著了一般佛掖。 火紅的嫁衣襯著肌膚如雪妖碉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天芥被,我揣著相機(jī)與錄音欧宜,去河邊找鬼。 笑死拴魄,一個胖子當(dāng)著我的面吹牛冗茸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匹中,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼夏漱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顶捷?” 一聲冷哼從身側(cè)響起挂绰,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎服赎,沒想到半個月后葵蒂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體交播,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年践付,在試婚紗的時候發(fā)現(xiàn)自己被綠了秦士。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡荔仁,死狀恐怖伍宦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乏梁,我是刑警寧澤次洼,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遇骑,受9級特大地震影響卖毁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜落萎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一亥啦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧练链,春花似錦翔脱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绿鸣,卻和暖如春疚沐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潮模。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工亮蛔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人擎厢。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓究流,卻偏偏與公主長得像,于是被迫代替她去往敵國和親动遭。 傳聞我的和親對象是個殘疾皇子梯嗽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,140評論 25 707
  • 我的好朋友和我喜歡的男生在一起了。 晴天霹靂沽损。五一假期結(jié)束灯节,睡足了覺醒來,刷微博看到T的最新動態(tài)。一句“H先森炎疆,余...
    蘇葉涼閱讀 785評論 3 6
  • 我喜歡優(yōu)雅和高效的代碼形入,代碼邏輯應(yīng)當(dāng)直截了當(dāng)全跨,叫缺陷難以隱藏;盡量減少依賴關(guān)系亿遂,使之便于維護(hù)浓若;依據(jù)某種分層戰(zhàn)略完善...
    小劉and12345閱讀 222評論 0 0
  • 又到了夜深人靜的時候了,室友們也都一一入睡蛇数,這個時候挪钓,仿佛整個世界都留給了我一人。結(jié)束了一天的喧囂耳舅,留下的寂靜碌上,讓...
    大小劉閱讀 287評論 0 0