一、UITableView
UITableView,也就是表視圖,可以算是app中最重要的視圖了,随處可見,中間這一圈就是,有一種清單的形勢,但應用比較豐富,可以加圖檔,每行的高度也可自定
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiNxYTN0YTMyIDNyIDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
UITableView繼承于UIScrollView,備其的滾動屬性
UITableView通過分區和行來劃分,每個分區為section,每行為row,編号都從0開始,系統專門提供了一個類NSIndexPath來整合section和row
從最基本最必要的說起吧
表視圖的初始化
//Grouped屬性,在滾動時分區頭部一起移動
UITableView *myTableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
//添加到父視圖
<pre name="code" class="objc"> [self.view addSubview: myTableView];
設定兩個代理
myTableView.delegate = self;//負責外觀
myTableView.dataSource = self;//負責資料
導入代理需要的兩個協定
@interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>
實作必須實作的兩個協定方法:
第一個,傳回表視圖每個分區的行數
//傳回每個分區下的單元格個數,必須實作
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
第二個,單元格的内容填充,這裡有兩種方法,注冊的方法和直接建立的方法
這裡有一個單元格重用機制的概念,大概的意思就是,螢幕顯示多少cell,系統就提供多少記憶體,滾動出螢幕的cell就讓自己的cell,給新滾動到螢幕上的cell使用
//定制每個單元格,indexPath:目前定位的單元格位置,它有兩個屬性:indexPath.section,indexPath.row
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell重用機制
//定義重用标示符
static NSString* cellId = @"CELL";
//每次需要使用單元格的是,先根據重用辨別符從重用隊列中擷取單元格,如果隊列中沒有,再進行初始化新的單元格
//每次都會先建立一螢幕的cell,當有cell出螢幕,就會根據重用辨別符添加到對應的重用隊列中,當螢幕外的cell要進入螢幕,先從隊列中擷取,如果沒有,則初始化cell
//當重用cell時,需要對上面的控件程式指派
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
//如果從重用隊列中未擷取cell,也就是Cell為空
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
//系統提供的控件要配合不同的樣式來使用
cell.detailTextLabel.text = @"detail詳細内容";
}
//選中效果
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//輔助視圖的樣式,右側會有一個小圖示
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//設定左側圖檔
cell.imageView.image = [UIImage imageNamed:@"b33"];
cell.textLabel.text = @"文字内容顯示";
//為相應位置傳回定制好的單元格
return cell;
}
//注冊單元格之後的寫法,不用判斷cell是否存在,不用初始化,直接使用
//需要在viewdidLoad中寫下面這行注冊代碼
//注冊單元格,
//第一個參數為所使用的單元格類型
//第二個參數為單元格的重用标示符
[myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"];
//但是無法修改cell的樣式,隻能使用default樣式
//-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];
// cell.detailTextLabel.text = @"asdas"; cell.textLabel.text = @"1111";// return cell;//
//}
cell自帶的imageVIew會随圖檔大小進行變化,下面的代碼會修改圖檔的大小
CGSize size = CGSizeMake(30, 40);
UIImage *image = [UIImage imageNamed:@"mv_book_icon"];
//調整image的大小
UIGraphicsBeginImageContextWithOptions(size, NO,0.0);
CGRect imageRect=CGRectMake(0.0, 0.0, size.width, size.height);
[image drawInRect:imageRect];
//設定圖檔
cell.imageView.image=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
寫了上面這些必須内容,就可以在界面上顯示出表視圖,能運作就不會有什麼錯誤
大概是下面的樣子,内容的圖檔和text可以自己改
因為模拟器的分辨率不夠,cell之間的分割線可能看不清
表視圖的問題很多的,還有很多屬性還是先上代碼,慢慢了解
下面的完整代碼添加了一些新内容:
TableView顯示相關的屬性:
//行高
myTableView.rowHeight = 70;
//分割線
myTableView.separatorColor = [UIColor blueColor];
myTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
//置頂視圖
myTableView.tableHeaderView = [[UIView alloc]init];
//置底視圖
myTableView.tableFooterView = [[UIView alloc]init];
//section标題的顔色
myTableView.sectionIndexColor = [UIColor redColor];
UITableViewCell的屬性
<span style="font-size:12px;"> //選中效果
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
//輔助視圖的樣式
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//設定左側圖檔
cell.imageView.image = [UIImage imageNamed:@"ck.jpg"];
//标題視圖
cell.textLabel.text = [NSString stringWithFormat:@"第%ld個cell,%ld個section",indexPath.row,indexPath.section];
//副标題視圖
cell.detailTextLabel.text = @"副标題";</span>
對row和section進行操作
//插入一行row
[self.myViewTable insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
//删除一行row
// [self.myViewTable deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
//删除一行row
// [self.myViewTable deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
//插入和删除section
NSIndexSet *section = [NSIndexSet indexSetWithIndex:1];
[self.myViewTable insertSections:section withRowAnimation:UITableViewRowAnimationFade];
[self.myViewTable deleteSections:section withRowAnimation:UITableViewRowAnimationTop];
//滾動到最後一行
[self.myViewTable scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
//滾動table到最底部
//目前内容已經超過一屏
if (_myTableView.contentSize.height >= _myTableView.bounds.size.height)
{
[self.myTableView setContentOffset:
CGPointMake(0, self.myTableView.contentSize.height -self.myTableView.bounds.size.height)animated:YES];
}
通過相關的代理方法來實作的:
設定指定位置cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
添加右側邊欄的索引條
-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
設定頁眉的高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
設定分區标題
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
添加點選cell的方法
點選cell會觸發方法
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
這裡有點重要東西,我們可以根據cell得到IndexPath,也可以根據IndexPath得到cell
同時也可以根據點選的cell得到cell的IndexPath,有時我們需要在點選cell的代理方法外得知這個點選的是哪個cell
//根據IndexPath得到cell
CustomTableViewCell *cell = [_myTableView cellForRowAtIndexPath:indexPath];
//根據cell得到IndexPath
NSIndexPath *indexPath2 = [_myTableView indexPathForCell:cell];
//根據點選得到cell的IndexPath
NSIndexPath *indexPath3 = [_myTableView indexPathForSelectedRow];
完整的代碼以及效果
#import "RootViewController.h"
@interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic,assign)int index;//标記建立單元格的個數
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
//初始化
self.index = 0;
self.navigationItem.title = @"表視圖學習";
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:200/255.0 green:233/255.0 blue:160/255.0 alpha:1];
//表視圖的初始化
//Grouped,分區頭部一起移動
UITableView *myTableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
[self.view addSubview: myTableView];
//tabView屬性
//分割線
myTableView.separatorColor = [UIColor colorWithRed:200/255.0 green:233/255.0 blue:160/255.0 alpha:1];
myTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
myTableView.rowHeight = 100;
//置頂視圖
// myTableView.tableFooterView = (一個石頭)
//表視圖所有的方法都需要代理方法
//表視圖的代理方法有兩個
//一個偏重于外觀
//一個偏重于資料
myTableView.delegate = self;
myTableView.dataSource = self;
//注冊單元格,
//第一個參數為所使用的單元格類型
//第二個參數為單元格的重用标示符
[myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"];
}
#pragma mark -- 表視圖的代理方法
//定制每個單元格,indexPath:目前定位的單元格位置,它有兩個屬性:indexPath.section,indexPath.row
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell重用機制
//定義重用标示符
static NSString* cellId = @"CELL";
//每次需要使用單元格的是,先根據重用辨別符從重用隊列中擷取單元格,如果隊列中沒有,再進行初始化新的單元格
//每次都會先建立一螢幕的cell,當有cell出螢幕,就會根據重用辨別符添加到對應的重用隊列中,當螢幕外的cell要進入螢幕,先從隊列中擷取,如果沒有,則初始化cell
//當重用cell時,需要對上面的控件程式指派
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
//如果從重用隊列中未擷取cell,也就是Cell為空
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
//系統提供的控件要配合不同的樣式來使用
cell.detailTextLabel.text = [NSString stringWithFormat:@"建立的第%d個單元格",self.index++];
}
//選中效果
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
//輔助視圖的樣式
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//設定左側圖檔
cell.imageView.image = [UIImage imageNamed:@"b33"];
cell.textLabel.text = [NSString stringWithFormat:@"第%ld個cell,%ld個section",indexPath.row,indexPath.section];
//為相應位置傳回定制好的單元格
return cell;
}
//注冊單元格之後的寫法,不用判斷cell是否存在,不用初始化,直接使用
//但是無法修改cell的樣式,隻能使用default樣式
//-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];
// cell.detailTextLabel.text = @"asdas";
//
// cell.textLabel.text = @"1111";
// return cell;
//
//}
//設定對應位置的cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//不同分區的寬度不同
//使得奇數cell的高度為50,偶數為100
if (indexPath.row%2 == 0 && indexPath.section %2 == 0) {
return 100;
}
else{
return 50;
}
}
//設定頁眉的高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 22;
}
//索引條
-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [NSArray arrayWithObjects:@"A",@"B",@"C", nil];
}
//點選cell之後執行的代理方法
//delect
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"點選了%ld分區下的%ld行的cell",indexPath.section,indexPath.row);
}
//添加分區标題
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return @"分區标題";
}
//傳回每個分區下的單元格個數,必須實作
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
//傳回分區的個數,可選實作,不實作則預設隻有一個分區
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 10;
}
@end
效果如下
内容有點多,下篇進行單元格的編輯和表視圖控制器