07_UI基础_UITableView实战- 支付宝口碑
此篇為針對ios中的UI基礎知識,為了能讓大家更清楚的理解,此整理中編寫了采用知識點+案例的方式,配有非常詳細的截圖和代碼注釋,添加了許多大白話進行解釋,如有錯誤之處,望指正,愿與您相互交流學習,共同進步!---"會飛的猴子_阿新"
本篇案例修改圖為(后面會逐步優化細節問題)
主要內容從支付寶案例開始,重點在后面哦!
使用UITableViewControler控制器實現支付寶口碑案例
UITableViewControler 缺陷: 現階段只適合全屏的..
01-UITableViewController體驗
- 相當于一個控制器自帶tableView
- viewController管理的是view
- tableViewController管理的是tableView
- 也就是在tableViewController下,self.view = self.tableView
02-tableView的HeaderView和FooterView
- tableView的header - (x, y, width) 可以隨便指定,(height) 實際數值
- tableView的footer - (y, width) 可以隨便指定,(x, height) 實際數值
創建一個demo體驗一下:
1.準備:新建文件-->把默認的的viewController刪掉-->新建LJXTableViewController-->把Main.storyboard中默認的控制器刪掉-->重寫拖拽一個UITableViewController-->指定初始箭頭,指定class.
2.添加頭部視圖
3.添加數據驗證一下頭部視圖跟 "一組和多組" 沒有關系
// // LJXTableViewController.m // LJX_tableView的頭部和尾部視圖#import "LJXTableViewController.h"@interface LJXTableViewController ()@end//重用標識 static NSString *ID = @"cell";@implementation LJXTableViewController- (void)viewDidLoad {[super viewDidLoad];UIView *headerView = [[UIView alloc]init];headerView.backgroundColor =[UIColor redColor];//把某個控件設置到tableHeaderView上時,只有高度需要我們自己設置,前面 X , Y ,Width都可以直接給個0headerView.frame = CGRectMake(0, 0, 0, 100);//設置tableView的最頂部視圖 注意:跟一組和多組沒有關系self.tableView.tableHeaderView = headerView;//-->這里只需要headerView賦值給tableHeaderView 這個屬性,內部就在添加到父控件上我們就不用addSubview://注冊cell[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID]; } //2組 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return 2; } //每組4行 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{return 4; }-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];cell.textLabel.text =@(indexPath.row).description;//簡單設置數據,每個cell顯示一個行數return cell; } @end4.添加底部視圖
UIButton *footerBtn = [[UIButton alloc]init];footerBtn.backgroundColor = [UIColor purpleColor]; //紫色背景//把某個控件設置到tableHeaderView上時,只有高度需要我們自己設置,前面 X , Y ,Width都可以直接給個0,但是x是可以改的,改了會有影響但不建議去改footerBtn.frame = CGRectMake(0, 0, 0, 100);//設置tableView的最底部視圖self.tableView.tableFooterView = footerBtn;03-星級評價-需求分析
1.滿星個數 "分數強轉成整形,如4.5轉成整形是4 那就表示有4顆滿星" 2.半星個數 "分數 - 整星個數如果不為0那說明就有一個半星" 3.空心個數 "for(NSInteger i = 已添加星星個數; i < 5; i++)"每一個商家的評分不一樣,所以分值要動態傳入,去動態設置星星樣子04-星級評價
4.1星級評價實現
創建實體文件夾,方便日后移植
為了方便最后整合代碼時的移植,不直接在控制器中實現,而是單獨創建繼承UIView的類,
4.2解決星星重復創建問題
我們只創建添加,沒有管過移除啥的,顧導致傳一次分,創建一次....
解決重復創建的問題
重寫初始化方法(初始化方法它只會調一次),那樣一創建leverStar這個控件,里面就自帶5顆星星imageView,
即對ZFBLeverStar.m做了修改
// // ZFBLeverStar.m // LJX_星級評價#import "ZFBLeverStar.h"@implementation ZFBLeverStar- (instancetype)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {//來了 直接把5個imageView創建添加好for (NSInteger i = 0; i < 5; i++) {UIImageView *imageView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"full_star"]];//這個目的不是拿圖片,目的是隨便拿一張圖片,圖片就有了大小了//設置圖片的xCGFloat imageViewX = i * imageView.image.size.width;imageView.frame = CGRectMake(imageViewX, 0, imageView.image.size.width, imageView.image.size.height);[self addSubview:imageView];}}return self; }//重寫set方法在里面處理顯示星星圖片的細節 -(void)setLever:(CGFloat)lever{_lever = lever;//1.滿星//把傳過來的分數強轉為整型,整數值就是滿星的個數NSInteger fullStartCount = (NSInteger)lever;for(NSInteger i = 0 ; i < fullStartCount ; i++){[self makeLeverStarWithImageName:@"full_star" andPosition:i];}//2.半星// (取傳過來的個數) - (強轉后的整數),如果 > 0 就表示有半星if((lever - fullStartCount)>0){[self makeLeverStarWithImageName:@"half_star" andPosition:fullStartCount];//如果添加了一個半星那把滿星個數的值做加1 用它當做 目前已經添加星星的總個數了fullStartCount++;}//3.空星 "如果到這來還不夠5顆星 那剩下的就是空星的個數了"for (NSInteger i = fullStartCount; i < 5; i++) {[self makeLeverStarWithImageName:@"empty_star" andPosition:i];} }/**創建星星imageView@param imageName 星星圖片@param position 星星位置 從0開始*/ -(void)makeLeverStarWithImageName:(NSString *)imageName andPosition:(NSInteger)position{//獲取相應位置的子控件UIImageView *imageView = self.subviews[position];//設置圖片imageView.image = [UIImage imageNamed:imageName]; }@end4.3 最后深入的優化
這次優化的目的是:日后星級評價更加的方便.--->外部不管用純代碼還有用xib還是用storyboard都比較方便.
如何不想使用代碼方式
使用storyboard
運行ok
支付寶口碑案例開始
自定義cell有3種方式,分別是storyboard,xib,手寫代碼.
我們都使用一遍.這里我們先使用第一種方式使用-->storyboard方式
需求分析
1.頂部是一個TableViewHeaderView 2.組的頭部標題可以停留,說明tableView是plain樣式 3.cell中的數據比較多,系統無法滿足,自定義cell1.項目準備:
指定類前綴(例如ZFB),分文件夾(目的是為了后面集成到一個項目中),刪除原有Main.storyboard 自己創建一個storyboard(指定class進行關聯,設置為啟動界面),并別忘指定 Main interface
創建控制器: 注意繼承UITableViewController(因為storyboard中我們拖拽的UITableViewControler,所以創建的類也要繼承UITableViewControler)
如果運行后,是白色面板. 排錯方法:打斷點
------>給數據源方法打斷點------->(沒執到時)-往上打斷點
------->[super viewDidLoad]----->(也沒有執行到時)
------>查看有沒有指定控制器class;
把準備好的plist文件和圖片素材拖入案例中
使用了UITableViewController后,指定數據源和遵守協議都不用我們管了.下一步我們來實現相應的數據源方法
2.實現相應的數據源方法
需要的數據,通過第4步會得到.
3.有多少行應該根據數據來
4.加載plist字典轉換模型
去modal文件夾中,創建模型類
5.在storyboard中給自帶的UITableViewCell指定重用標識 一定要和返回cell的數據源方法是的標識要一樣
UITableView *cell = [tableView dequeueReusableCellWithIdentifier:@"business" forIndexPath:indexPath];6.在storyboard中給cell添加拖拽相應的控件,并添加約束
6.1拖拽imageView
(plus是3X的在這除以3
工作中一般都2x的,到時候除以2)
因為各個商家圖片不一樣大,顧為了統一
Scale:拉伸圖片
Aspect:圖片長寬的比例,保持圖形的長寬比,保持圖片不變形。
Aspect Fill:在保持長寬比的前提下,縮放圖片,使圖片充滿容器。
Aspect Fit:在保持長寬比的前提下,縮放圖片,使得圖片在容器內完整顯示出來。
Scale to Fill: 縮放圖片,使圖片充滿容器。圖片未必保持長寬比例協調,有可能會拉伸至變形。
6.1拖拽lable設置店名
6.3 先拖個view給星星占個位,后面再處理
得
6.4拖拽lable設置評分
設置約束
6.4拖拽lable設置人均消費
設置字體大小,設置約束
運行一下看效果,然后再繼續
6.5拖拽lable設置折扣
設置約束
6.6拖拽lable設置距離
設置約束 x和Y
6.7拖拽lable設置減字
設置約束(上邊距8,與上面左邊對齊,)略
減字外面的是正方形,我們設置一下寬高比為1:1,文字居中就ok了
6.8拖拽lable設置隨機立減...
(設置字體及顏色,設置約束,略..)
6.9 修改一下cell的高度
上面修改了business中的高度,只是修改了模型的大小,運行起來還得看 table View的高度大小,所以還得修改table View的高度
6.10 把背景顏色去掉運行一下看看
7.創建一個繼承至UITableViewCell的類,并且指定SB中的UITableViewCell的class為自己創建出來的這個類
8.把SB中Cell內部的子控件連線到指定class的.m中的延展中
8.1增加一個延展
8.2指定class
8.3 子控件連線
9.把模型變成屬性定義在自定義cell類的.h中,在.m重寫模型屬性的set方法在此方法設置數據
9.1 把模型變成屬性定義在自定義cell類的.h中
9.2 在.m重寫模型屬性的set方法在此方法設置數據
回到ZFBBusinessController.m中
修改創建的cell類型
設置數據
運行看現階段效果
數據類型有點小問題,8.8折和9.8折后面都一大串,接下來修改
10.打折 把模型中的offNum 改float類型,前提要改一下引入系統框架 UIKit
10.1修改ZFBBusinessModel.h文件
10.2修改ZFBBusinessCell.m文件
運行看效果
11.集成星星,把星星的文件拖拽出來后,指定Storyboard中代表星星的那個View的Class
12.把用來表示星星view連線在自定義cell.m中,引入星星類的頭文件
13.在模型屬性的set方法中,給星星view傳level
_leverView.lever = businessModel.level;
上面報錯是因為我們傳的是CGFloat類型導致的
而
顧改一下
這是這里又報錯
還要改一下
把星星后面黃色背景顏色去掉,運行看效果
14.創建了一個xib 把xib中的view 寬361 高960
15.在里面拖入一個imageView并且設置好圖片, 注意先 com + = 自適應下 為了后面使用Aspect ratio后圖片不會變形
16. 第一個imageView 上 左 右 8間距 + 寬高比
先使用 com + = 自適應 ,后面再設置寬高比,這樣他會根據真實的尺寸算比例,圖片不會變形
17.再復制3個imageView 但注意它身上約束
即復制完后,clear復制的約束
18.全部選中(com+a) 左對齊 等寬等高 上下間距8
左對齊
等寬等高
上下間距8:
注意在設置上下間距前,要保證兩個圖片之間不要有重合
19.創建一個繼承 至UIView的類,并且給xib指定class
繼承關系是跟最頂層有關系的,最頂層是UIView,就繼續UIView,最頂層是UIButton,那就繼續UIButton. 這里是頂層是UIView.
給xib指定class(其實不指定也可以,因為之間沒有連線,但最好指定一下,說明它們之間是同一類型)
20.把加載xib細節封裝在剛才創建的類中,提供一個可以讓外部調用的類方法,目的降低耦合度.
//######################### // ZFBBusinessPictureView.h #import <UIKit/UIKit.h>@interface ZFBBusinessPictureView : UIView/**加載xib創建頭部視圖*/ +(instancetype)businessPictureView;@end//######################### // ZFBBusinessPictureView.m #import "ZFBBusinessPictureView.h"@implementation ZFBBusinessPictureView/*知識點回顧--兩種加載xib的方式1.NSBundle加載XIB iOS 2.0 的方法2.使用UINib加載XIB iOS 4.0 的方法 做了內存優化"如果內存緊張"內存警告,可以自動釋放,如果有需要會重新自動加載""*/+(instancetype)businessPictureView{UINib *nib = [UINib nibWithNibName:@"ZFBBusinessPicture" bundle:nil];return [[nib instantiateWithOwner:nil options:nil]firstObject]; }@end21.給tableView設置tableHeaderView 注意要計算它將來真實的高度
回到ZFBBusinessController.m
回到控制器中,導入剛才創建類的頭文件ZFBBusinessPictureView.h
在控制器設置tableView的頭部 視圖.
22.給tableView設置tableFooterView
//3.設置tableView的尾部視圖UIButton *footerBtn = [[UIButton alloc]init];[footerBtn setTitle:@"點擊加載更多" forState:UIControlStateNormal];[footerBtn setTitleColor:[UIColor colorWithWhite:0.3 alpha:1] forState:UIControlStateNormal];[footerBtn setTitleColor:[UIColor colorWithWhite:0.7 alpha:1] forState:UIControlStateHighlighted];footerBtn.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1];footerBtn.frame = CGRectMake(0, 0, 0, 30);self.tableView.tableFooterView = footerBtn;//設置為尾部視圖23.實現沒點擊加載更多一次,多輸出一個cell
把之前定義是不可變數組,修改為可變數組,不然就會報警告
24.優化讓其自動滾動
1.atScrollPosition: 的參數為UITableViewScrollPositionMiddle時
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.businessData.count-1 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
2.atScrollPosition: 的參數為UITableViewScrollPositionBottom時
25.細節處理 讓cell的分割線從最左邊開始
self.tableView.separatorInset = UIEdgeInsetsZero;后面還沒會慢慢對細節進行處理
檢測自己
看看哪些沒掌握:
1、能夠說出tableViewController的view屬性和tableView是一樣的
2、能夠使用xib布局口碑的頭部視圖
3、能夠說出使用代碼重新設置nib高度的含義是為了適配不同寬度的屏幕
4、能夠使用代碼設置尾部的按鈕
5、能夠說出代碼會調用view的initWithFrame方法
6、能夠說出sb/xib會調用view的aweakFromNib方法
7、能夠將星級評價小框架移植到口碑控制器中
8、能夠解決浮點數轉字符串精度的問題
9、能夠使用代碼解析plist數據
)
10、能夠使用代碼將字典轉化成模型
11、能夠使用代碼設置tableView的headerView和footerView
簡單回顧過程
1.口碑-數據分析
2.口碑-創建模型
- 類前綴
- 分文件夾
- 素材
3.口碑-解析數據
4.口碑-通過sb加載cell
- 通過sb加載cell,需要設置cell的Identifier,給sb中的cell設置重用標識即完成注冊單元格
5.口碑-cell的布局
1.商家配圖圖片大小不一樣,所以最好給imageView設置寬高約束,達到配圖尺寸統一 2.label如果只有一行時,只用設置位置即可,尺寸讓它自適應 3.評分view,它的大小不能自適應,所以必須設置寬高約束"60,12" 4.減是個方形的,所以最好設置個寬高比店名字體:14字體 其它是12號字體 到cell邊距15 內部邊距116.口碑-自定義cell控件連線
1.cell中的子控件不能連線到控制器,因為當前控制器只有一個,但是將來cell有很多個,所以會報重復連接"連線"錯誤 2.正確作法,應該創建一個繼承至UITableViewCell的類,來管理"描述/表示",設置cell的customClass 3.把cell中子控件的連線,連入到管理cell類的.m的延展中7.口碑-設置cell數據
引入模型屬性"strong" 重寫模型屬性set方法給cell內部子控件設置數據8.口碑-移植星級評價
- 拖拽文件,設置sb中的view為自定義view,連線并在set數據的方法中把數據放在控件上
- 用自定義星星的類來描述cell中的星星view,加載sb中的小星星view創建出來的對象,就是他指定類創建來出的對象"他們是同一個東西了"
- 再給level傳入分值即可
9.口碑-頭部視圖-布局
- 第一個視圖分別設置 上,左,右,寬高比
- 后面的視圖與前一個等寬,等高,垂直間距,水平居中
10.口碑-頭部視圖-代碼設置縮放比例
- 在xib中調整好位置高度,并在視圖加載完成之后根據'寬度'和'屏幕的寬度'和'屏幕的高度'設置**高度** - tableView的寬 / xib中HeaderView的寬 * xib中HeaderView的高 得到按比例縮放后的realHeaderView的高 - xib中的高 * tableView的寬 / xib中的寬 - xib的高 / xib的寬 * tableView的寬 2: 3 == 4: 6?11.口碑-尾部視圖
- 灰度,R=G=B
- 1為白色 0為黑色
12.口碑-組頭
- tableview兩種樣式組頭的區別?
- grouped跟著tableView滾動出去
- plain可以懸停在上方
13.口碑-添加導航控制器
Editor -> Embedin -> Navgation Contorller
20-MarkMan測量截圖位置
21-KVC
// 方法1 傳統寫法_name = dict[@"name"];// 字典不能保存基本數據類型_age = [dict[@"age"] integerValue]; // 方法2 KVC - `間接`通過 key 設置數值// 注意:基本數據類型,不需要轉換,KVC 可以自動實現轉換![self setValue:dict[@"name"] forKey:@"name"];[self setValue:dict[@"age"] forKey:@"age"]; // 方法3 KVC - 進階,循環遍歷字典for (NSString *key in dict) {// 1. 通過 key 取值id value = dict[key];// 2. 通過 KVC 方法設置數值// -key 對應對象的 `屬性`,如果屬性不存在就崩潰[self setValue:value forKey:key];} // 方法4 KVC 字典轉模型大招 -> 內部實際上就是方法3的實現[self setValuesForKeysWithDictionary:dict];- 在保證模型的屬性和字典中的key相同的情況下,字典轉模型使用setValuesForKeysWithDictionary:方法
- keys value coding 鍵值編碼
附整體代碼
/**總步驟:1.指定類前綴,分文件夾'刪除原有Main.sb' 自己創建一個,并別忘指定 Main interface2.實現相應的數據源方法3.有多少行應該根據數據來4.加載plist字典轉換模型5.在sb中給自帶的UITableViewCell指定重用標識 一定要和返回cell的數據源方法是的標識要一樣6.在SB中給cell添加拖拽相應的控件,并添加約束7.創建一個繼承至UITableViewCell的類,并且指定SB中的UITableViewCell的class為自己創建出來的這個類8.把SB中Cell內部的子控件連線到指定class的.m中的延展中9.把模型變成屬性定義在自定義cell類的.h中,在.m重寫模型屬性的set方法在此方法設置數據10.打折 把模型中的offNum 改float類型,前提要改一下引入系統框架 UIKit11.集成星星,把星星的文件拖拽出來后,指定SB中代表星星的那個View的Class 12.把用來表示星星view連線在自定義cell.m中,引入星星類的頭文件13.在模型屬性的set方法中,給星星view傳level14.創建了一個xib 把xib中的view 寬361 高96015.在里面拖入一個imageView并且設置好圖片, com + = 自適應下 為了不用改寬高比約束值16. 第一個imageView 上 左 右 8間距 + 寬高比17. 復制3個imageView 但注意它身上約束18. 全部選中左對齊 等寬等高 上下間距819. 創建一個繼承 至UIView的類,并且指定class20. 把加載xib細節封裝在此類中,提供一個可以讓外部調用的類方法21.給tableView設置tableHeaderView 注意要計算它將來真實的高度22.給tableView設置tableFooterView23.實現沒點擊加載更多一次,多輸出一個cell24.優化讓其自動滾動25.細節處理 讓cell的分割線從最左邊開始 */ //********************ZFBBusinessController.h***************************** // ZFBBusinessController.h #import <UIKit/UIKit.h>@interface ZFBBusinessController : UITableViewController@end//**********************ZFBBusinessController.m*************************** // // ZFBBusinessController.m // LJX_支付寶口碑(stroyboard搭建)#import "ZFBBusinessController.h" #import "ZFBBusinessModel.h" #import "ZFBBusinessCell.h" #import "ZFBBusinessPictureView.h"@interface ZFBBusinessController () //數據在多個數據源方法中使用,顧聲明一個屬性 @property (nonatomic ,strong)NSMutableArray *businessData; @end@implementation ZFBBusinessController- (void)viewDidLoad {[super viewDidLoad];//1.加載數據self.businessData = [self loadBusinessData];//-->使用方式2時,直接調用方法就行[self loadBusinessData];//2.設置tableView的頭部視圖ZFBBusinessPictureView *pictureView = [ZFBBusinessPictureView businessPictureView];//如果不設置,因為xib中設置的寬度是361,如果在375的手機屏幕上顯示,因為xib中的圖片的寬度沒有寫死,當到了寬屏幕下,變寬,高也會變高,導致圖片會超出父控件, 出了頭部視圖的邊界.//375 * 960 / 361CGFloat pictureViewHeight = self.tableView.bounds.size.width * pictureView.bounds.size.height / pictureView.bounds.size.width; //計算真實高度pictureView.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, pictureViewHeight); //寬度最好不要給了,以防有問題self.tableView.tableHeaderView = pictureView; //設置為頭部視圖//3.設置tableView的尾部視圖UIButton *footerBtn = [[UIButton alloc]init];[footerBtn setTitle:@"點擊加載更多" forState:UIControlStateNormal];// colorWithWhite:0.3 alpha:1 通過灰度來設置顏色 第一個參數如果 傳0就是黑色 如果傳1就表示白色[footerBtn setTitleColor:[UIColor colorWithWhite:0.3 alpha:1] forState:UIControlStateNormal];[footerBtn setTitleColor:[UIColor colorWithWhite:0.7 alpha:1] forState:UIControlStateHighlighted];footerBtn.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1];footerBtn.frame = CGRectMake(0, 0, 0, 30);[footerBtn addTarget:self action:@selector(loadMoreData) forControlEvents:UIControlEventTouchUpInside]; //添加點擊事件self.tableView.tableFooterView = footerBtn;//設置為尾部視圖//小細節處理 :讓分割線從最左邊開始self.tableView.separatorInset = UIEdgeInsetsZero;}#pragma mark -尾部按鈕點擊后會調用此方法 //1.加載更多數據 -(void)loadMoreData{//1.創建一個新的模型ZFBBusinessModel *businessModel = [[ZFBBusinessModel alloc]init];businessModel.icon = @"ss";businessModel.discount = @"全場大派送,2元一件,快來買!";businessModel.averagePrice = @2;businessModel.distance = @20;businessModel.offNum = 2;businessModel.level = 5;businessModel.name = @"西單大悅城!";//2.把新模型添加到保存所以數據的數組中[self.businessData addObject:businessModel];//3.讓數據源方法重新執行[self.tableView reloadData];NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.businessData.count-1 inSection:0];[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];}#pragma mark -數據源方法 // 應該口碑案例表格就1組,默認就1組,所以不用再寫 //- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ // return 1; //}// 行數 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.businessData.count;//--->使用方式2時: return _businessList.count; }// -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{//1.創建cellZFBBusinessCell *cell = [tableView dequeueReusableCellWithIdentifier:@"business" forIndexPath:indexPath];//-->這里在storyboard中進行注冊cell//2.設置數據 (傳遞模型,這里是單組數據展示, 當只有一組數據的時候用row,多組的時候才先用section再用row)cell.businessModel = self.businessData[indexPath.row];//3.返回cellreturn cell; }#pragma mark -加載數據- (NSMutableArray *)loadBusinessData{//1.加載plistNSMutableArray *dictArr = [NSMutableArray arrayWithContentsOfURL:[[NSBundle mainBundle]URLForResource:@"business.plist" withExtension:nil]];//2. 創建可變數組保存模型 /k?'p?s?t?/ 容量NSMutableArray *arryM = [NSMutableArray arrayWithCapacity:dictArr.count];//3.字典轉模型for(NSDictionary *dict in dictArr){[arryM addObject:[ZFBBusinessModel businessWithDict:dict]];/* 分步寫//3.1 把字典傳遞給模型,讓模型設置自己的屬性ZFBBusinessModel *groupModel = [ZFBBusinessModel businessWithDict:dict];//3.2 把創建好的模型添加到可變數組中.[arryM addObject: groupModel];*/}return arryM; }/*方式2. 加載數據方法的返回值設置為空 ,聲明一個成員變量(給成員變量設置泛型),把可變數組賦值給成員變量1. NSArray<ZFBBusinessModel *> *_businessList; //聲明成員變量,設置泛型2.- (void)loadBusinessData{...code略...._businessList = arryM;}*/@end // // ZFBBusinessModel.h #import <UIKit/UIKit.h>@interface ZFBBusinessModel : NSObject ///頭像 @property (nonatomic, copy) NSString *icon; ///優惠信息 @property (nonatomic, copy) NSString *discount; ///人均消費 @property (nonatomic, strong) NSNumber *averagePrice; ///距離 @property (nonatomic, strong) NSNumber *distance; ///打折 //浮點數字轉出成字符串時,可能會出現問題,把它轉換成float @property (nonatomic, assign) float offNum; ///評分 @property (nonatomic, assign) CGFloat level; ///店名 @property (nonatomic, copy) NSString *name;+ (instancetype)businessWithDict:(NSDictionary *)dict;@end #import "ZFBBusinessModel.h"@implementation ZFBBusinessModel+(instancetype)businessWithDict:(NSDictionary *)dict{id obj = [[self alloc]init];[obj setValuesForKeysWithDictionary:dict];//--->注意使用KVC編碼,屬性名和字典中的key的名字一定要相同.return obj; }@end // // ZFBLeverStar.h // LJX_星級評價#import <UIKit/UIKit.h>@interface ZFBLeverStar : UIView ///接收評分 @property (nonatomic, assign) CGFloat lever;@end // // ZFBLeverStar.m // LJX_星級評價#import "ZFBLeverStar.h"@implementation ZFBLeverStar//當一個視圖從xib或storyboard中創建完成之后就會調用此方法 -(void)awakeFromNib{[super awakeFromNib];//來了 直接把5個imageView創建添加好for (NSInteger i = 0; i < 5; i++) {UIImageView *imageView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"full_star"]];//這個目的不是拿圖片,目的是隨便拿一張圖片,圖片就有了大小了//設置圖片的xCGFloat imageViewX = i * imageView.image.size.width;imageView.frame = CGRectMake(imageViewX, 0, imageView.image.size.width, imageView.image.size.height);[self addSubview:imageView];} }//此方法只有用代碼創建時才會調用 - (instancetype)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {//來了 直接把5個imageView創建添加好for (NSInteger i = 0; i < 5; i++) {UIImageView *imageView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"full_star"]];//這個目的不是拿圖片,目的是隨便拿一張圖片,圖片就有了大小了//設置圖片的xCGFloat imageViewX = i * imageView.image.size.width;imageView.frame = CGRectMake(imageViewX, 0, imageView.image.size.width, imageView.image.size.height);[self addSubview:imageView];}}return self; }//重寫set方法在里面處理顯示星星圖片的細節 -(void)setLever:(CGFloat)lever{_lever = lever;//1.滿星//把傳過來的分數強轉為整型,整數值就是滿星的個數NSInteger fullStartCount = (NSInteger)lever;for(NSInteger i = 0 ; i < fullStartCount ; i++){[self makeLeverStarWithImageName:@"full_star" andPosition:i];}//2.半星// (取傳過來的個數) - (強轉后的整數),如果 > 0 就表示有半星if((lever - fullStartCount)>0){[self makeLeverStarWithImageName:@"half_star" andPosition:fullStartCount];//如果添加了一個半星那把滿星個數的值做加1 用它當做 目前已經添加星星的總個數了fullStartCount++;}//3.空星 "如果到這來還不夠5顆星 那剩下的就是空星的個數了"for (NSInteger i = fullStartCount; i < 5; i++) {[self makeLeverStarWithImageName:@"empty_star" andPosition:i];} }/**創建星星imageView@param imageName 星星圖片@param position 星星位置 從0開始*/ -(void)makeLeverStarWithImageName:(NSString *)imageName andPosition:(NSInteger)position{//獲取相應位置的子控件UIImageView *imageView = self.subviews[position];//設置圖片imageView.image = [UIImage imageNamed:imageName]; }@end/*//1.創建imageView設置圖片,那么imageView創建出來的就有尺寸UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:imageName]];//2.設置圖片的xCGFloat imageViewX = position * imageView.image.size.width;imageView.frame = CGRectMake(imageViewX, 0, imageView.image.size.width, imageView.image.size.height);[self addSubview:imageView];*/ // // ZFBBusinessCell.h#import <UIKit/UIKit.h> @class ZFBBusinessModel; @interface ZFBBusinessCell : UITableViewCell ///模型屬性 注意模型是個對象 用strong @property (nonatomic , strong) ZFBBusinessModel *businessModel;@end // // ZFBBusinessCell.m#import "ZFBBusinessCell.h" #import "ZFBBusinessModel.h"//注意導入頭文件 #import "ZFBLeverStar.h" @interface ZFBBusinessCell () ///商店的頭像 @property (weak, nonatomic) IBOutlet UIImageView *iconView; ///店名 @property (weak, nonatomic) IBOutlet UILabel *nameLabel; ///評分 @property (weak, nonatomic) IBOutlet UILabel *levelLabel; ///人均消費 @property (weak, nonatomic) IBOutlet UILabel *averagePriceLabel; ///打折 @property (weak, nonatomic) IBOutlet UILabel *offNumLabel; ///距離 @property (weak, nonatomic) IBOutlet UILabel *distanceLabel; ///優惠信息 @property (weak, nonatomic) IBOutlet UILabel *discountLabel; ///星級評價 @property (weak, nonatomic) IBOutlet ZFBLeverStar *leverView;@end@implementation ZFBBusinessCell//重寫模型屬性的set方法在此方法中給子控件設置數據 -(void)setBusinessModel:(ZFBBusinessModel *)businessModel{_businessModel =businessModel;_iconView.image = [UIImage imageNamed:businessModel.icon];_nameLabel.text = businessModel.name;_levelLabel.text = @(businessModel.level).description;//level是NSNumber類型的,轉字符串掉description方法_averagePriceLabel.text = [NSString stringWithFormat:@"人均消費 %@ 元",businessModel.averagePrice]; //plist中只存了個數字,要顯示人均消費**元,顧要拼接字符串_offNumLabel.text = [NSString stringWithFormat:@"%@ 折",@(businessModel.offNum).description];_distanceLabel.text = [NSString stringWithFormat:@"距離北京石油化工學院 %@ m",businessModel.distance];_discountLabel.text = businessModel.discount;//傳分_leverView.lever = businessModel.level; }- (void)awakeFromNib {[super awakeFromNib];// Initialization code }- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated];// Configure the view for the selected state }@end // // ZFBBusinessPictureView.h#import <UIKit/UIKit.h>@interface ZFBBusinessPictureView : UIView/**加載xib創建頭部視圖*/ +(instancetype)businessPictureView;@end // // ZFBBusinessPictureView.m#import "ZFBBusinessPictureView.h"@implementation ZFBBusinessPictureView/*知識點回顧--兩種加載xib的方式1.NSBundle加載XIB iOS 2.0 的方法2.使用UINib加載XIB iOS 4.0 的方法 做了內存優化"如果內存緊張"內存警告,可以自動釋放,如果有需要會重新自動加載""*/+(instancetype)businessPictureView{UINib *nib = [UINib nibWithNibName:@"ZFBBusinessPicture" bundle:nil];return [[nib instantiateWithOwner:nil options:nil]firstObject]; }@end轉載于:https://www.cnblogs.com/ljx-xinge/p/07UI-ji-chuUITableView-shi-zhan-zhi-fu-bao-kou-bei.html
總結
以上是生活随笔為你收集整理的07_UI基础_UITableView实战- 支付宝口碑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年山东省ACM省赛总结
- 下一篇: 人生须要沉淀