主要提綱:
一、表視圖
二、UITableViewCell的重用機(jī)制
三、UITableview的相關(guān)配置(代理方法)
四、UITableView自適應(yīng)高速
五、UITableView的編輯(增、刪、移動(dòng))
六、成品展示
一、表視圖(UItableView)
1、什么是表視圖?
表視圖 UITableView,iOS中最重要的視圖,隨處可 。
表視圖通常 來管理 組具有相同數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)。
例圖:
UITableView的使用圖片.png
二、UITableViewCell的重用機(jī)制
1、為什么要使用UITableViewCell的重用機(jī)制?
表視圖的重用機(jī)制:當(dāng)表視圖的單元格超過一屏幕時(shí),這時(shí)就會(huì)啟動(dòng)cell重用機(jī)制。當(dāng)滑動(dòng)時(shí)單元格出屏幕時(shí),就會(huì)把相同格式的單元格放在同一個(gè)集合中,為這個(gè)集合添加標(biāo)識符,當(dāng)我們需要使用某種樣式的單元格時(shí),根據(jù)不同的標(biāo)示符,從集合中尋找單元格,出屏幕的cell會(huì)被添加到mutableSet中,進(jìn)入屏幕的cell,先從set中獲取,如果獲取不到,才創(chuàng)建一個(gè)cell。在cell顯示之前,給cell賦上相應(yīng)的內(nèi)容。
// 定義單元格 indexPath:單元格當(dāng)前所在的位置
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 相當(dāng)于從集合中找尋完全出屏幕的單元格
// identifier: 因?yàn)橐粋€(gè)表視圖中可能存在多種樣式的單元格,咋們把相同格式的單元格放在同一個(gè)集合里,為這個(gè)集合加標(biāo)識符,當(dāng)我們需要用到某種樣式的單元格時(shí),根據(jù)不同的標(biāo)識符,從集合中找尋單元格
static NSString *identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// 如果從集合中未找到單元格,也就是集合中還沒有單元格,也就是還沒有單元格完全出屏幕,那么我們就需要?jiǎng)?chuàng)建單元格
if (!cell) {
// 創(chuàng)建cell的時(shí)候需要標(biāo)示符,是因?yàn)楫?dāng)該cell觸屏幕的時(shí)候需要根據(jù)標(biāo)示符放到對應(yīng)的集合中
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
三、UITableview的相關(guān)配置(代理方法)
1 、UITableView的創(chuàng)建與配置
#import "RootViewController.h"
@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,retain)NSArray *dataArray; // 數(shù)據(jù)源,用來給cell賦值的
@property (nonatomic,retain)NSArray *dataArray1;
@property (nonatomic,retain)NSDictionary *datadic;
@property (nonatomic,retain)NSMutableArray *titleArray; // 用來盛放頭標(biāo)題
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化數(shù)據(jù)源并且添加數(shù)據(jù)
self.dataArray = [NSArray arrayWithObjects:@"小心如",@"林心如",@"趙薇",@"林志穎",
@"LOL",@"劉毅",@"仝文哲",@"成龍",
@"丁大",@"武松", nil];
self.dataArray1 = [NSArray arrayWithObjects:@"大喬恩",@"陳喬恩",@"趙薇",@"林志穎",
@"LOL",@"劉毅",@"仝文哲",@"成龍",
@"丁大",@"武松", nil];
self.datadic = [NSDictionary dictionaryWithObjectsAndKeys:self.dataArray,@"one",self.dataArray1,@"two", nil];
// 添加頭標(biāo)題
for (NSArray *arrayIten in self.datadic.allValues) {
// 從數(shù)組中取出第一個(gè)元素
// 判斷字典中的元素釋放存在,如果存在它的類型是否是數(shù)組
if (arrayIten && [arrayIten isKindOfClass:[NSArray class]] && arrayIten.count) {
NSString *nameStr = [arrayIten objectAtIndex:0];
// 判斷數(shù)組中的元素是否存在,如果存在類型是否為字符串,如果為字符串,判斷字符串長短是否為0
if (nameStr && [nameStr isKindOfClass:[NSString class]] && nameStr.length) {
// 截取字符串的首個(gè)字符
NSString *resultStr = [nameStr substringToIndex:1];
[self.titleArray addObject:resultStr];
NSLog(@"%@",resultStr);
}
}
}
self.navigationItem.title = @"今日頭條";
// 初始化一個(gè)UItableView
// style:設(shè)置單元格的樣式 有兩種樣式:plain(平鋪) group(分組) 默認(rèn)是平鋪
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) style:UITableViewStyleGrouped];
// 設(shè)置分割線樣式
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
tableView.separatorColor = [UIColor greenColor];
/**
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine,
UITableViewCellSeparatorStyleSingleLineEtched
*/
// 如果我們每個(gè)cell的高度是統(tǒng)一的,可以直接使用屬性設(shè)置
tableView.rowHeight = 200;
tableView.backgroundColor = [UIColor orangeColor];
//UItableView 的代理
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
}
2、相關(guān)代理
#pragma mark -- 共有多少個(gè)分區(qū)
// 共有多少個(gè)分區(qū) (此方法是可選的,如果不實(shí)現(xiàn)該代理方法,默認(rèn)整個(gè)表視圖只有一個(gè)分區(qū))
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
// 返回字典在中元素的個(gè)數(shù),作為分區(qū)的個(gè)數(shù)
return self.datadic.count;
}
#pragma mark -- 每個(gè)分區(qū)下返回的行數(shù)
// 每個(gè)分區(qū)下返回的行數(shù)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// 返回所有數(shù)據(jù)的個(gè)數(shù) 這里單元格的返回個(gè)數(shù)一般不寫死,將數(shù)據(jù)源的個(gè)數(shù)作為返回值,根據(jù)數(shù)據(jù)的數(shù)量來創(chuàng)建單元格的數(shù)量
// return [self.dataArray count];
// // 根據(jù)當(dāng)前所在的分區(qū),取得字典中對應(yīng)的鍵
// NSString *keyString = self.datadic.allKeys[section];
// NSLog(@"%@",keyString);
// // 根據(jù)鍵取出對應(yīng)的值,由于字典的值為數(shù)組,所以可以有count屬性
// return [self.datadic[keyString] count];
// 根據(jù)所在分區(qū)取出字典中的(值)
NSArray *array = [self.datadic.allValues objectAtIndex:section];
return array.count;
}
#pragma mark -- 定義單元格
// 定義單元格 indexPath:單元格當(dāng)前所在的位置
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 表視圖的重用機(jī)制:當(dāng)表視圖的單元格超過一屏幕時(shí),這時(shí)就會(huì)啟動(dòng)cell重用機(jī)制。當(dāng)滑動(dòng)時(shí)單元格出屏幕時(shí),就會(huì)把相同格式的單元格放在同一個(gè)集合中,為這個(gè)集合添加標(biāo)識符,當(dāng)我們需要使用某種樣式的單元格時(shí),根據(jù)不同的標(biāo)示符,從集合中尋找單元格
//出屏幕的cell會(huì)被添加到mutableSet中,進(jìn)入屏幕的cell,先從set中獲取,如果獲取不到,才創(chuàng)建一個(gè)cell。在cell顯示之前,給cell賦上相應(yīng)的內(nèi)容。
static NSString *identifier = @"cell";
// 相當(dāng)于從集合中找尋完全出屏幕的單元格
// identifier: 因?yàn)橐粋€(gè)表視圖中可能存在多種樣式的單元格,咋們把相同格式的單元格放在同一個(gè)集合里,為這個(gè)集合加標(biāo)識符,當(dāng)我們需要用到某種樣式的單元格時(shí),根據(jù)不同的標(biāo)識符,從集合中找尋單元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// 如果從集合中未找到單元格,也就是集合中還沒有單元格,也就是還沒有單元格完全出屏幕,那么我們就需要?jiǎng)?chuàng)建單元格
if (!cell) {
// 創(chuàng)建cell的時(shí)候需要標(biāo)示符,是因?yàn)楫?dāng)該cell觸屏幕的時(shí)候需要根據(jù)標(biāo)示符放到對應(yīng)的集合中
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
/*
UITableViewCellStyleDefault, // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
UITableViewCellStyleValue1, // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
UITableViewCellStyleValue2, // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
UITableViewCellStyleSubtitle // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
*/
// 設(shè)置cell的style,不涉及到數(shù)據(jù)的重新賦值,咋們可以在初始化cell的時(shí)候給他設(shè)定好
// 設(shè)置輔助視圖的樣式 (枚舉值,有多種樣式)
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
/**
UITableViewCellAccessoryNone, // don't show any accessory view
UITableViewCellAccessoryDisclosureIndicator, //灰色小箭頭 // regular chevron. doesn't track
UITableViewCellAccessoryDetailDisclosureButton // 藍(lán)圈號 // info button w/ chevron. tracks
UITableViewCellAccessoryCheckmark, // 對號 // checkmark. doesn't track
UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED // info button.
*/
// 設(shè)置選中后的效果
cell.selectionStyle = UITableViewCellSelectionStyleNone;
/**
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray,
UITableViewCellSelectionStyleDefault
*/
}
四、UITableView自適應(yīng)高速
#pragma mark -- 自適應(yīng)高速
// 返回cell高度的代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
// NSString有一個(gè)方法,可以根據(jù)內(nèi)容返回一個(gè)矩形大小
// 代理方法的執(zhí)行是有順序的,這里視線執(zhí)行返回高度的代理方法,在執(zhí)行創(chuàng)建單元格的代理方法
// 取得內(nèi)容
NSDictionary *dic = [self.dataArray objectAtIndex:indexPath.row ];
NSString *contentStr = [dic objectForKey:@"content"];
// 內(nèi)容自適應(yīng)高度的方法
/**
* 參數(shù)解釋:
* size:是規(guī)定文本顯示的最大范圍
* options:按照和中設(shè)置來計(jì)算范圍
* taaributes:文本內(nèi)容的一些屬性,例如;字體大小。字體的類型
* context:上下文,可以規(guī)定一些其他設(shè)置,但是一般都是nil
*/
// 枚舉值中的單或(|),意思是要滿足所有的枚舉值設(shè)置
CGRect rect = [contentStr boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, MAXFLOAT) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil];
return rect.size.height+60;
}
五、UITableView的編輯(增、刪、改)
1、 打開編輯狀態(tài)
// 設(shè)置導(dǎo)航條右側(cè)編輯按鈕,如果設(shè)置表視圖為可編輯狀態(tài),點(diǎn)擊此處按鈕就會(huì)有相應(yīng)的操作
self.navigationItem.rightBarButtonItem = self.editButtonItem;
// 設(shè)置表視圖的編輯狀態(tài) (重寫系統(tǒng)的方法 ,而不是代理方法)
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
// 設(shè)置tableView為可編輯狀態(tài)
[self.tableView setEditing:editing animated:animated];
}
2、 設(shè)置課編輯狀態(tài)下的表視圖哪個(gè)單元格可編輯,
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
// 不想首個(gè)單元格可編輯
if (indexPath.row == 0) {
return NO;
}
// 直接返回YES,默認(rèn)所有單元格都是可以編輯的
return YES;
}
3. 設(shè)置編輯樣式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
// 讓最后一行為插入數(shù)據(jù)樣式
if (indexPath.row == (self.dataMutableArray.count - 1)) {
return UITableViewCellEditingStyleInsert;
}
// 默認(rèn)所有的單元格都是刪除樣式
return UITableViewCellEditingStyleDelete;
}
4、編輯(刪除,增加)
// 編輯完成之后執(zhí)行的代理方法
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
// 此方法根據(jù)編輯樣式的不同,來做出不同的邏輯操作
// 如果編輯樣式為刪除是執(zhí)行的操作
if (editingStyle == UITableViewCellEditingStyleDelete) {
// 先刪除當(dāng)前單元格上現(xiàn)實(shí)的數(shù)據(jù)
[self.dataMutableArray removeObjectAtIndex:indexPath.row];
// 刪除單元格
/**
indexPaths:此參數(shù)為數(shù)組,數(shù)組中的元素類型是NSIndexPath類型,說明此方法可以刪除多個(gè)單元格
Animation:刪除動(dòng)作的動(dòng)畫
*/
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationBottom];
}else if (editingStyle == UITableViewCellEditingStyleInsert){
// 先增加一條數(shù)據(jù)
// [self.dataMutableArray insertObject:@"叼毛獸" atIndex:indexPath.row];
[self.dataMutableArray insertObject:@"叼毛獸" atIndex:self.dataMutableArray.count - 1];
// 在增加單元格
[tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}
}
4、編輯(移動(dòng)單元格)
// 移動(dòng)單元格
- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
// 默認(rèn)YES,所有的單元格都可以移動(dòng)
return YES;
}
//
/** 移動(dòng)完成會(huì)執(zhí)行的代理方法
* @param sourceIndexPath 當(dāng)前移動(dòng)單元格原來所在的位置
* @param destinationIndexPath 移動(dòng)完成后所在的新位置
*/
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
// 把要移動(dòng)位置的數(shù)據(jù)先保存起來
NSString *string = [NSString stringWithString:[self.dataMutableArray objectAtIndex:sourceIndexPath.row]];
// 刪除原來位置的數(shù)據(jù)
[self.dataMutableArray removeObjectAtIndex:sourceIndexPath.row];
// 把此數(shù)據(jù)插入到數(shù)組中新位置
[self.dataMutableArray insertObject:string atIndex:destinationIndexPath.row];
}
六、成品展示
1、成品
5F11AA6F-8C6A-4990-A753-3C1F72D10F3F.png
2、移動(dòng)
097AA0D8-BBE6-4E8C-A9C1-6EE2235A5DCD.png
3、刪除
370316CA-B9C5-4844-BC4D-C921B71A0967.png
4、增加
A28C976F-5CA0-43AF-8993-2BA9F3EB148A.png