一.搭建界面
1.分析界面 需要使用什么控制器來(lái)管理
我們根據(jù)需求 ? 可以用一個(gè)UITableViewController來(lái)管理
2.分析需求,我們發(fā)現(xiàn)cell的樣式是固定的 ?系統(tǒng)的cell不能滿足我們的需求
我們需要自定義cell ? ?創(chuàng)建cell類,同時(shí)創(chuàng)建xib
3.如何加載xib文件
3.1 可以提供一個(gè)類方法快速創(chuàng)建
+ (instancetype)cell
{return[[[NSBundlemainBundle]loadNibNamed:@"XMGSubTagCell"owner:niloptions:nil]firstObject]; ?}
通過(guò)NSBundle加載xib描述cell,一定要記得綁定標(biāo)示符, 而且在創(chuàng)建cell的時(shí)候 ?還要判斷是否為空
XTSubTagCell*cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if(cell ==nil) {
cell = [XTSubTagCellcell];
}
3.2 可以通過(guò)注冊(cè)的方式 ? ? ?可以不用綁定標(biāo)識(shí)符,也可以不做判斷是否為空
二.加載數(shù)據(jù)
1.查看接口文檔(基本url,請(qǐng)求參數(shù),請(qǐng)求方式)
2.驗(yàn)證接口能否請(qǐng)求成功,查看服務(wù)器返回的數(shù)據(jù) ? 為什么?
(接口文檔有可能描述錯(cuò)誤,要自己去驗(yàn)證一下)
3.發(fā)送AFN請(qǐng)求
3.1 創(chuàng)建管理者對(duì)象
3.2 設(shè)置請(qǐng)求參數(shù)
3.3 發(fā)送請(qǐng)求
4.解析數(shù)據(jù)(寫成pilst文件 ?分析數(shù)據(jù))
5.設(shè)計(jì)模型,字典轉(zhuǎn)模型
6.把模型展示到界面
怎么做?
6.1 在cell里面定義模型屬性來(lái)接收模型數(shù)據(jù)
6.2 在cell里面定義要接收數(shù)據(jù)的屬性
6.3 重寫模型屬性的set方法
6.4 給需要接收數(shù)據(jù)的參數(shù)賦值
7.設(shè)置完成 ?運(yùn)行項(xiàng)目,發(fā)現(xiàn)tableView還是沒(méi)有數(shù)據(jù)? 為什么
因?yàn)閠ableView只在啟動(dòng)的時(shí)候調(diào)用了一次數(shù)據(jù)源方法,這個(gè)時(shí)候還沒(méi)有數(shù)據(jù) ? ? ? 設(shè)置完數(shù)據(jù)沒(méi)有調(diào)用數(shù)據(jù)源方法
什么時(shí)候會(huì)重新調(diào)用數(shù)據(jù)源方法?
1 tableView第一次被加載的時(shí)候
2?刷新tableView表格
解決: 加載完數(shù)據(jù)之后(發(fā)送網(wǎng)絡(luò)成功),刷新tableView表格 ?就會(huì)重新調(diào)用數(shù)據(jù)源方法
[self.tableViewreloadData];
三.cell內(nèi)部結(jié)構(gòu)處理
1.訂閱數(shù)字處理
1.1 為什么要處理訂閱數(shù)字?
訂閱數(shù)非常大的時(shí)候,1萬(wàn)以上,我們希望顯示為:XX萬(wàn)人訂閱
2.2 在哪里處理?
我們?cè)赾ell里面賦值的時(shí)候可以拿到訂閱數(shù) ?可以在cell內(nèi)部做處理
2.3?怎么處理?
拿到訂閱數(shù)(String類型),轉(zhuǎn)換成CGFloat類型 ? ? ? ?顯示為XX人訂閱
CGFloatnumF = item.sub_number.floatValue;
判斷一下不超過(guò)1萬(wàn) 直接顯示, ? 超過(guò)一萬(wàn) ? 訂閱數(shù) /1萬(wàn) ? 保留一位小數(shù) ? 顯示為XX萬(wàn)人訂閱
2.4 如果正好是1萬(wàn)的整數(shù)倍 ? 那么處理后的數(shù)據(jù)為XX.0萬(wàn)人 ??我們希望 .0 不要顯示 ? ? ?怎么處理?
可以利用字符串替換
// 以后字符串不想要,就替換為空
numStr = [numStrstringByReplacingOccurrencesOfString:@".0"withString:@""];
2.頭像圓角處理
2.1 怎么處理?
有三種處理方式設(shè)置圓角半徑 ? 圖片裁剪 ?運(yùn)行時(shí)
2.11 圖片裁剪 ? ?怎么做? ? 在哪里寫代碼?
0.在cell里面賦值的時(shí)候可以拿到圖片 ?可以在cell內(nèi)部做處理
1.開啟圖形上下文
// UIGraphicsBeginImageContextWithOptions:繪制圖片不清晰
// scale:比例因子 像素與點(diǎn)比例 0:自動(dòng)識(shí)別
UIGraphicsBeginImageContextWithOptions(image.size,NO,0);
2.設(shè)置圓形裁剪區(qū)域
UIBezierPath*path = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0, image.size.width, image.size.height)];
3.超出裁剪區(qū)域剪切掉
[pathaddClip];
4.繪圖
[imagedrawAtPoint:CGPointZero];
5. 獲取圖片
image =UIGraphicsGetImageFromCurrentImageContext();
6.關(guān)閉圖形上下文
UIGraphicsEndImageContext();
2.12 設(shè)置圓角半徑 ?在哪里寫代碼?
因?yàn)閏ell從xib加載,一定會(huì)調(diào)用awakeFromNib
// 當(dāng)對(duì)象從xib加載完成就會(huì)調(diào)用
// 只會(huì)調(diào)用一次
- (void)awakeFromNib
{
//??? self.iconView.layer.cornerRadius = self.iconView.frame.size.width * 0.5;
//??? // 超出主層邊框,就會(huì)裁剪掉
//??? self.iconView.layer.masksToBounds = YES;不設(shè)置的話, 看到的圖片還是原來(lái)的形狀(正方形)
}
2.13 運(yùn)行時(shí)
在xib里面 ?選中要設(shè)置圓角的圖片的imageView
3.分割線處理
3.1 為什么要處理分割線
系統(tǒng)的分割線沒(méi)有占據(jù)整個(gè)cell ? ?離cell得左邊有一段距離 ? ?我們希望分割線占據(jù)整個(gè)cell
3.2 怎么處理?
1.自定義分割線
2.設(shè)置系統(tǒng)屬性,讓分割線占據(jù)全屏(iOS6和iOS7,iOS7和iOS8)
首先 ?我們要知道 ? ?分割線屬于tableView的內(nèi)容
在tableView里面搜IOS7 ? 可以查看到IOS7版本新出來(lái)的API
我們找到一個(gè)內(nèi)邊距 ? 嘗試設(shè)置一下
// 取消分割線內(nèi)邊距
self.tableView.separatorInset=UIEdgeInsetsZero;
設(shè)置完之后我們發(fā)現(xiàn)分割線確實(shí)往左邊移了一點(diǎn),但還是沒(méi)占據(jù)整個(gè)cell(ios8或以上的用戶會(huì)有這個(gè)問(wèn)題 ? ios7或一下的沒(méi)有)
我們知道IOS8之后 ?出了一個(gè)layOut的內(nèi)邊距,整個(gè)屬性屬于UIView
我們?nèi)IView里面去搜索IOS8新出的API ? 搜索到layoutMargins
// 取消約束邊緣
self.tableView.layoutMargins=UIEdgeInsetsZero;
設(shè)置完之后我們發(fā)現(xiàn)沒(méi)有效果 ,為什么?
可能是我們?cè)O(shè)置的對(duì)象搞錯(cuò)了,我們嘗試一下給cell設(shè)置一下
cell.layoutMargins=UIEdgeInsetsZero;
設(shè)置完之后,我們發(fā)現(xiàn)就可以了 ?問(wèn)題解決了
layoutMargins是IOS8de內(nèi)容 ?我們項(xiàng)目設(shè)置的支持的最低版本為ios7,那么ios7用戶使用ios8的api會(huì)報(bào)錯(cuò)
怎么解決?
判斷一下 ? ?ios8以上的就不執(zhí)行這個(gè)方法
怎么拿到當(dāng)前手機(jī)版本
#define XTSystemVersion ([UIDevice currentDevice].systemVersion.floatValue)
if(XTSystemVersion>=8.0) {// 8.0以上才需要調(diào)用方法
cell.layoutMargins=UIEdgeInsetsZero;
}
3.setFrame重寫cell的setFrame 1.取消系統(tǒng)分割線 2.設(shè)置tableView背景色為分割線顏色
優(yōu)點(diǎn):不用做屏幕適配 ? 任何地方都能使用
設(shè)置cell的分割線,那么應(yīng)該是設(shè)置cell的frame ? 在cell類里面寫代碼
怎么寫?
0 取消系統(tǒng)的分割線
1 先設(shè)置tableView的背景顏色 ? ?想讓分割線為什么顏色就設(shè)置背景色為什么顏色
2 只需要設(shè)置frame的高度比cell的高度小一點(diǎn)就可以了
- (void)setFrame:(CGRect)frame
{讓cell的y值從10 的位置開始顯示
frame.origin.y+=10;
讓cell左右距離父控件左右間距為10
frame.origin.x+=10;
frame.size.width-=20;
設(shè)置分割線的高度
frame.size.height-=10;
// 還原系統(tǒng)實(shí)現(xiàn)
// 真正設(shè)置cell的frame
[supersetFrame:frame];
}
3 ? 如果分割線高度太大 ?,那么cel的內(nèi)容可能顯示不完全, ? 應(yīng)為cell的高度減小了
怎么解決?
我們只要把cell的高度設(shè)置大一點(diǎn)就可以了 ? ?分割線高度設(shè)置多少 ?我們就在原來(lái)的基礎(chǔ)上給cell的高度再加多少
四.發(fā)送網(wǎng)絡(luò)請(qǐng)求,提示正在加載的HUD
1.為什么要使用HUD?
給用戶良好的體驗(yàn)
2.怎么使用HUD?
用cocoapods導(dǎo)入SVProgressHUD框架
// 提示用戶當(dāng)前正在加載數(shù)據(jù)
[SVProgressHUDshowWithStatus:@"正在加載數(shù)據(jù)ing...."];
3.什么時(shí)候顯示HUD
發(fā)送網(wǎng)絡(luò)請(qǐng)求的時(shí)候(之前), ?進(jìn)入推薦標(biāo)簽界面就發(fā)送網(wǎng)絡(luò)請(qǐng)求,所以可以在viewDidLoad方法里面顯示
4.什么時(shí)候隱藏
數(shù)據(jù)加載完成或者是用戶退出界面的時(shí)候
// 隱藏指示器
[SVProgressHUDdismiss];
5.注意點(diǎn):
當(dāng)網(wǎng)絡(luò)非常慢的時(shí)候,用戶可能不等網(wǎng)絡(luò)請(qǐng)求完畢就退出當(dāng)前界面,這個(gè)時(shí)候就要隱藏HUD而且關(guān)閉網(wǎng)絡(luò)請(qǐng)求
那么,我們應(yīng)該把代碼寫在哪里??
界面消失的時(shí)候回調(diào)用下面的方法,我們可以把代碼寫在這里面
- (void)viewWillDisappear:(BOOL)animated
{
[superviewWillDisappear:animated];
// 隱藏指示器
[SVProgressHUDdismiss];
// 干掉請(qǐng)求
// 讓管理者中所有任務(wù)全部執(zhí)行cancel
[_mgr.tasksmakeObjectsPerformSelector:@selector(cancel)];
}