@(iOS 項目實戰(zhàn))[項目實戰(zhàn)]
- 作者: Liwx
- 郵箱: 1032282633@qq.com
目錄
- 新帖登錄界面運行效果
- 1.新帖
- 推薦標(biāo)簽搭建
- 推薦標(biāo)簽相關(guān)知識點
- 2.關(guān)注和登陸界面
- 使用xib搭建關(guān)注界面
- 使用xib搭建登陸界面
- xib使用注意
新帖登錄界面運行效果
1.新帖
推薦標(biāo)簽搭建
- 1.在push方法中統(tǒng)一設(shè)置跳轉(zhuǎn)到非根控制器隱藏tabBar,必須在push前隱藏tabBar
// ----------------------------------------------------------------------------
// 重寫pushViewController:方法,在跳轉(zhuǎn)前統(tǒng)一設(shè)置返回按鈕
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// ------------------------------------------------------------------------
// 1.判斷如果不是根控制器,則設(shè)置viewController控制器返回按鈕
if (self.childViewControllers.count > 0) {
// 必須在push前隱藏tabBar
viewController.hidesBottomBarWhenPushed = YES;
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem backItemWithImage:[UIImage imageNamed:@"navigationButtonReturn"] highImage:[UIImage imageNamed:@"navigationButtonReturnClick"] target:self action:@selector(back) title:@"返回"];
}
[super pushViewController:viewController animated:animated];
}
- 2.設(shè)置推薦標(biāo)簽的標(biāo)題兩種方式,
self.title = @"標(biāo)題文字"
,必須在非根控制器的時候才能這么使用
,否則有問題.
// 方式一
self.navigationItem.title = @“推薦標(biāo)簽”;
// 方式二,只有在非根控制器的時候才能這么使用,否則有問題.
self.title = @“推薦標(biāo)簽”;
-
3.獲取推薦標(biāo)簽網(wǎng)絡(luò)數(shù)據(jù)
- 接口文檔
- 基本url: http://mobads.baidu.com/cpro/ui/mads.php
- 請求方式: GET
- 請求參數(shù)(必選): 參數(shù)tag_recommend,sub,topic
- 1.創(chuàng)建請求回話管理者
- 2.設(shè)置響應(yīng)體的數(shù)據(jù)格式,添加@"text/html"(可選)
// ------------------------------------------------------------------------ // 2. 設(shè)置響應(yīng)體的數(shù)據(jù)格式,添加@"text/html" AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; serializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil]; manager.responseSerializer = serializer;
3.拼接請求參數(shù)
-
4.發(fā)送請求,請求廣告數(shù)據(jù)
- 4.1 獲取廣告數(shù)據(jù) ,返回的廣告數(shù)據(jù)是數(shù)組,有[],所以要用lastObject取出數(shù)據(jù)
- 4.2 字典轉(zhuǎn)模型
mj_objectWithKeyValues:方法作用是將字典轉(zhuǎn)換成對應(yīng)的模型
- 4.3 設(shè)置廣告界面的數(shù)據(jù),返回數(shù)據(jù)中有廣告圖片的尺寸
注意
廣告界面bug: 服務(wù)器返回的圖片寬度有可能為0,需判斷寬度是否為0,否則會出現(xiàn)NaN崩潰錯誤
,原因是因為除以0
, 不等于0才可以除. - 4.4 添加點擊手勢,點擊圖片跳轉(zhuǎn)到廣告頁
- 默認(rèn)UIImageView是不能與用戶交互的,必須先
設(shè)置userInteractionEnabled屬性為YES
;
- 默認(rèn)UIImageView是不能與用戶交互的,必須先
參考代碼
// ---------------------------------------------------------------------------- // 請求廣告數(shù)據(jù) - (void)loadAdData { // ------------------------------------------------------------------------ // 1.創(chuàng)建請求回話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // ------------------------------------------------------------------------ // 2. 設(shè)置響應(yīng)體的數(shù)據(jù)格式,添加@"text/html" AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; serializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil]; manager.responseSerializer = serializer; // ------------------------------------------------------------------------ // 3.拼接請求參數(shù) NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"code2"] = code2; // ------------------------------------------------------------------------ // 4.請求廣告數(shù)據(jù) [manager GET:@"http://mobads.baidu.com/cpro/ui/mads.php" parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 判斷取回來的數(shù)據(jù)是否正確 // 4.1 獲取廣告數(shù)據(jù) ,返回的廣告數(shù)據(jù)是數(shù)組,有[],所以要用lastObject取出數(shù)據(jù) NSDictionary *adDict = [responseObject[@"ad"] lastObject]; // 判斷是否請求到數(shù)據(jù),如果沒有數(shù)據(jù),則退出 if (adDict == nil) { return; } // 4.2 字典轉(zhuǎn)模型 mj_objectWithKeyValues:方法作用是將字典轉(zhuǎn)換成對應(yīng)的模型 WXAdItem *adItem = [WXAdItem mj_objectWithKeyValues:adDict]; self.adItem = adItem; // 4.3 設(shè)置廣告界面的數(shù)據(jù),返回數(shù)據(jù)中有廣告圖片的尺寸 CGFloat w = screenW; // NaN:除以0, 不等于0才可以除 if (adItem.w) { // 計算寬高比例 CGFloat h = screenW / adItem.w * adItem.h; UIImageView *adImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, w, h)]; [adImageView sd_setImageWithURL:[NSURL URLWithString:adItem.w_picurl]]; [self.adView addSubview:adImageView]; adImageView.userInteractionEnabled = YES; // 4.4 添加點擊手勢,點擊圖片跳轉(zhuǎn)到廣告頁 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)]; [adImageView addGestureRecognizer:tap]; } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@", error); }]; }
- 接口文檔
- 4.搭建推薦標(biāo)簽界面
-
1.加載xib中cell的兩種方式
-
NSBundle方式(必須在
xib綁定標(biāo)識
才能循環(huán)利用cell)
static NSString * const ID = @"cell"; // 從緩沖池獲取cell WXSubTagCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) { // 從xib創(chuàng)建cell cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([WXSubTagCell class]) owner:nil options:nil] lastObject]; }
-
注冊方式(使用
self.tableView registerNib
方法注冊,可以不用在xib中綁定標(biāo)識
)
// 在viewDidLoad方法中注冊cell [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([WXSubTagCell class]) bundle:nil] forCellReuseIdentifier:ID];
-
NSBundle方式(必須在
2.展示cell數(shù)據(jù)
-
3.處理cell中的細(xì)節(jié)
- 圓形頭像處理
- 方式一: 在awakeFromNib設(shè)置頭像的圓角半徑
layer.cornerRadius
并裁減masksToBounds
.
- 方式一: 在awakeFromNib設(shè)置頭像的圓角半徑
- (void)awakeFromNib { self.iconImageView.layer.cornerRadius = self.iconImageView.bounds.size.width * 0.5; self.iconImageView.layer.masksToBounds = YES; }
- 方式二: 在xib中使用KVC設(shè)置(不建議使用)
- 圓形頭像處理
-
- 方式三: 先裁減圖片,再顯示到iconImageView
- 訂閱數(shù)(子標(biāo)題)處理
- 處理訂閱數(shù)(超過萬的時候處理,讓小數(shù)點如果是.0,不顯示.0,通過字符串替換,將.0替換成空串)
- cell分割線處理(具體如下操作)
- 5.cell分割線處理
方式一: 用
UIView自定義分割線
.方式二: 利用系統(tǒng)
tableView的separatorInset屬性
.處理系統(tǒng)分割線(分割線靠最左邊):
設(shè)置cell的layoutMargins
屬性,只支持iOS8以上.-
方式三:
重寫cell的setFrame實現(xiàn)(常用)
- 1.
取消系統(tǒng)的樣式
separatorStyle為UITableViewCellSeparatorStyleNone - 2.設(shè)置tableView的背景色為分割線的顏色,目的是為了
讓露出的背景部分充當(dāng)分割線
. - 3.重寫cell的setFrame方法,內(nèi)部需先調(diào)用[super setFrame:frame];讓frame的高度屬性減去一個值,比如減去1,如果要讓分割線更寬,減去的值為更大值即可.
- cell的尺寸和位置是在每次刷新表格/表格要顯示的時候,先把所有cell位置全部計算出來.當(dāng)cell要顯示的時候,會從剛剛計算好的位置取出來給cell賦值.
- 1.
方式三實現(xiàn)參考代碼
// WXSubTagViewController.m中取消tableView原本的分割線,設(shè)置tableView的背景色為分割線顏色
// ----------------------------------------------------------------------------
// 設(shè)置分割線,需在cell內(nèi)部將cell高度-1,這樣讓漏出的背景充當(dāng)分割線
- (void)setupSeparatorLine
{
// 分割線: 1.自定義分割線 2.利用系統(tǒng)屬性 3.重寫cellsetFrame
// 4.取消系統(tǒng)的分割線
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 設(shè)置tableView背景色,之后將cell的高度-1,漏出的背景充當(dāng)分割線
self.tableView.backgroundColor = WXColor(206, 206, 206);
}
// 在WXSubTagCell.m中
// ----------------------------------------------------------------------------
// 重寫setFrame方法,目的是為了讓分割線占據(jù)屏幕整個寬度
- (void)setFrame:(CGRect)frame
{
// 露出1pt充當(dāng)背景分割線,
frame.size.height -= 1;
[super setFrame:frame];
}
-
6.AFN取消請求業(yè)務(wù)
- 發(fā)送請求前彈出指示器
- .在viewWillDisappear方法中隱藏指示器
- 在viewWillDisappear方法中使用AFHttpSessionManager的tasks屬性(tasks是數(shù)組), 讓數(shù)組里面的每個任務(wù)都調(diào)用cancel方法取消任務(wù).
- viewWillDisappear方法內(nèi)部實現(xiàn)參考代碼
// ---------------------------------------------------------------------------- // 取消網(wǎng)絡(luò)請求任務(wù), 控制器的view即將消失的時候調(diào)用 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // 取消所有網(wǎng)絡(luò)任務(wù) [self.mgr.tasks makeObjectsPerformSelector:@selector(cancel)]; // 隱藏指示器 [SVProgressHUD dismiss]; }
推薦標(biāo)簽相關(guān)知識點
-
裁減圖片步驟(存在鋸齒)
- 1.開啟位圖上下文(
自適應(yīng)位圖上下文比例
) - 2.貝塞爾曲線描述裁減路徑
- 3.設(shè)置裁減區(qū)域
- 4.繪圖
- 5.從上下文獲取才叫好的圖片
- 6.關(guān)閉上下文
- 7.用抗鋸齒分類設(shè)置圓形圖片抗鋸齒(抗鋸齒實現(xiàn)原理: 生成1像素的圖形邊框)
- 裁減圖片參考代碼
// 1.開啟位圖上下文(自適應(yīng)位圖上下文比例) UIGraphicsBeginImageContextWithOptions(image.size, NO, 0); // 2.貝塞爾曲線描述裁減路徑 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; // 3.設(shè)置裁減區(qū)域 [path addClip]; // 4.繪圖 [image drawAtPoint:CGPointZero]; // 5.從上下文獲取裁剪好的圖片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); // 6.關(guān)閉上下文 UIGraphicsEndImageContext(); // 7.用抗鋸齒分類設(shè)置圓形圖片抗鋸齒(抗鋸齒實現(xiàn)原理: 生成1像素的圖形邊框) self.iconImageView.image = [newImage imageAntialias];
- 1.開啟位圖上下文(
-
tableView優(yōu)化
- 幀數(shù)小于45就會出現(xiàn)明顯感覺卡頓現(xiàn)象
- iOS9不需要擔(dān)心圓角使幀數(shù)降低
-
觀察刷新幀數(shù)工具: Core Animation工具(只能在真機(jī)上才能觀察)
打開Core Animation
Xcode的工具軟件,選中Core Animation
Core Animation界面
2.關(guān)注和登陸界面
使用xib搭建關(guān)注界面
-
1.UILabel文字換行
- 1.UILabel在
xib實現(xiàn)換行按option + 回車
. - 2.代碼實現(xiàn)換行只需在顯示的文本添加\n
即可換行.
- 1.UILabel在
-
2.自動布局關(guān)注界面
- 1.設(shè)置立即登陸注冊按鈕為Custom類型,并設(shè)置按鈕普通/高亮狀態(tài)顯示的內(nèi)容.
3.綁定xib的管理類,并設(shè)置xib的view為控制器的view
-
關(guān)注界面效果圖
使用xib搭建登陸界面
- 1.劃分結(jié)構(gòu): 采用
占位視圖思想
(3部分,頂部,中間,底部)
xib設(shè)計圖
運行效果圖,橙色背景色只是為方便分析而添加的.
2.設(shè)置背景圖片
-
3.布局頂部關(guān)閉和注冊帳號按鈕
- 1.設(shè)置注冊帳號按鈕普通/選中狀態(tài)的文字.
-
4.自定義中間登陸LoginRegisterView
1.添加和帳號和密碼的文本框背景一樣尺寸的view,作為占位視圖
2.添加ImageView到占位視圖view中,
-
3.設(shè)置帳號密碼文本框左右間距
-
修改文本框樣式Border Style
-
-
4.設(shè)置登陸按鈕
- 1.通過代碼或使用xib設(shè)置(xib中KVC方式設(shè)置)設(shè)置圓角半徑并裁減.
- 2.在awakeFromNib方法中獲取按鈕的背景圖片,并重新生成拉伸中間1x1的圖片.
獲取按鈕當(dāng)前狀態(tài)背景圖片:currentBackgroundImage屬性獲取當(dāng)前按鈕狀態(tài)的背景圖片
.
-
5.在同一個xib描述兩個不同的view
- 1.提供一個快速創(chuàng)建登陸view的類方法
-
2.提供一個快速創(chuàng)建注冊view的類方法
-
6.登陸和注冊界面動畫
-
1.通過修改約束來實現(xiàn)修改登陸和注冊界面的位置,從
xib中將最左邊的間距拖入代碼成為屬性
.
-
2.點擊注冊按鈕實現(xiàn)自動布局動畫參考代碼
-
更新約束強(qiáng)制刷新方法layoutIfNeeded
,如果沒有調(diào)用layoutIfNeeded方法,不會立即更新
.
-
-
// ---------------------------------------------------------------------------- // 注冊按鈕點擊 - (IBAction)registerOrLogin:(UIButton *)sender { // 1.切換選中狀態(tài) sender.selected = !sender.isSelected; // 2.更新約束 self.leftMargin.constant = self.leftMargin.constant == 0 ? -screenW : 0; // 3.執(zhí)行動畫(更新約束動畫刷新方法layoutIfNeeded) [UIView animateWithDuration:0.25 animations:^{ // 3.1 強(qiáng)制刷新 [self.view layoutIfNeeded]; }]; }
- 7.通過
xib創(chuàng)建的控件,加載時默認(rèn)是xib的位置尺寸
.從xib加載的view必須再重新設(shè)置frame來適配不同屏幕
.- 1.
不要在viewDidLoad方法中重新設(shè)置frame
,最好在viewDidLayoutSubviews方法中重新設(shè)置xib中view的frame
.
- 1.
-
5.底部快速登陸界面
- 1.布局底部三個第三方登陸按鈕.
- 2.自定義按鈕,調(diào)整按鈕的位置,讓圖標(biāo)顯示在上面,標(biāo)題顯示在下面.
- 投機(jī)方式: 通過
改變按鈕的imageView和titleLabel內(nèi)邊距
(不建議使用) -
自定義FastLoginButton
并重寫layoutSubviews重新布局
按鈕的子控件,圖片放置頂部,標(biāo)題放置底部.-
重新計算文字的寬度,在給titleLabel寬度賦值,否則會出現(xiàn)文字用…顯示
.使用[self.titleLabel sizeToFit]
就能解決.
-
- 投機(jī)方式: 通過
-
3.設(shè)置快速登陸UILabel和左右兩邊的線條UIImageView,設(shè)置UIImageView的contentMode,左邊線設(shè)置為Right模式,右邊先設(shè)置為Left模式.
xib使用注意
1.從xib加載的view必須要重新設(shè)置位置和尺寸.
2.不要在viewDidLoad方法中重新設(shè)置frame,最好
在viewDidLayoutSubviews方法中重新設(shè)置xib中view的frame
.