一.UITableView
<p>tableView 是項目開發(fā)里經常用到的控件埋嵌,剛開始使用時可能會覺得這玩意功能強大但實現起來復雜,不過用多了俱恶,就會覺得它功能強大而且簡單雹嗦。
<p>分類 tableView有兩種風格范舀,每次初始化時必須制定一種風格,默認是 Plain了罪,而且創(chuàng)建成功后是不可更改的锭环,所以希望通過一個tableView實例在兩種風格之間互相切換的少年實在是想多了。
UITableViewStylePlain
:section 的headers和footers是漂浮在內容上層的捶惜,而且這種風格的列表可以在右側有一個索引條田藐,通過索引直接跳轉到對應的section。
UITableViewStyleGrouped
:有默認的background color和background view 吱七,iOS7之前每個分組都有圓角效果感覺挺叼,不過iOS7扁平化之后跟UITableViewStylePlain也沒啥區(qū)別了鹤竭,而且不能使用索引功能踊餐。
<p>創(chuàng)建 tableView必須有一個協(xié)議的實現類和數據源的實現類。
// 1.初始化plain風格的table臀稚,plain可以使用索引功能
self.plainTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 80, self.view.bounds.size.width, self.view.bounds.size.height - 80)];
self.plainTableView.dataSource = self;// 設置數據源
self.plainTableView.delegate = self;// 設置代理
//2.實現數據源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
return cell;
}
<p>屬性 tableView通過屬性設置各項數值
self.plainTableView.tag = 10001;
self.plainTableView.rowHeight = 92;// 單元格高度吝岭,優(yōu)先級比 -tableView:heightForRowAtIndexPath:低
self.plainTableView.sectionHeaderHeight = 40;
self.plainTableView.sectionFooterHeight = 40;
self.plainTableView.estimatedRowHeight = 92;// 估算單元格高度,(iOS7)
self.plainTableView.estimatedSectionHeaderHeight = 40;// 估算section頭部視圖高度吧寺,(iOS7)
self.plainTableView.estimatedSectionFooterHeight = 40;// 估算section尾部視圖高度窜管,(iOS7)
self.plainTableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 20);// 分割線間隙,(iOS7)
self.plainTableView.backgroundColor = [UIColor whiteColor];// 背景色
self.plainTableView.backgroundView = nil;// 背景視圖稚机,想要顯示背景視圖必須先把單元格的背景色設為clearColor
<p>編輯 tableView由單元格組成幕帆,每個單元格都具有選中屬性,實現了tableView的單選和多選赖条,不過tableView存在編輯模式和普通模式失乾,所以選擇也分為編輯模式下和普通模式下的單選和多選,默認只能在普通模式下單選纬乍。除此之外單元格的選中也分為多個樣式:
- UITableViewCellSelectionStyleNone
- UITableViewCellSelectionStyleBlue
- UITableViewCellSelectionStyleGray
- UITableViewCellSelectionStyleDefault (iOS7)
self.plainTableView.allowsSelection = YES;// 默認是YES碱茁,決定單元格在非編輯模式下是否可單選
self.plainTableView.allowsSelectionDuringEditing = NO;// 默認是NO,決定單元格在編輯狀態(tài)下是否可單選
self.plainTableView.allowsMultipleSelection = NO;// 默認是NO仿贬,決定單元格在非編輯模式下是否可多選纽竣,不被allowsSelection影響
self.plainTableView.allowsMultipleSelectionDuringEditing = NO;// 默認是NO,決定單元格仔編輯狀態(tài)下是否可多選茧泪,當該值被設為YES時蜓氨,列表的編輯模式將沒有刪除、添加
<p>信息 tableView有許多方法獲取自身的各項屬性
// 獲取number
NSInteger numOfSection = [self.plainTableView numberOfSections];
NSInteger numOfRowInSection0 = [self.plainTableView numberOfRowsInSection:0];
NSLog(@"%d%d",numOfSection,numOfRowInSection0);
// 獲取Frame
CGRect sectionRect = [self.plainTableView rectForSection:0];// 包括section頭部視圖和尾部視圖的
CGRect headerRect = [self.plainTableView rectForHeaderInSection:0];
CGRect footerRect = [self.plainTableView rectForFooterInSection:0];
CGRect cellRect = [self.plainTableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
NSLog(@"%f%f%f%f",sectionRect.size.height,headerRect.size.height,footerRect.size.height,cellRect.size.height);
// 獲取indexPath
NSIndexPath *indexPath0 = [self.plainTableView indexPathForRowAtPoint:CGPointMake(10, 200)];// 當點不在列表任意單元格中的時候返回nil
NSIndexPath *indexPath1 = [self.plainTableView indexPathForCell:[self.plainTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]]];// 當單元格不可見的時候返回nil
NSArray *indexPathArr0 = [self.plainTableView indexPathsForRowsInRect:CGRectMake(0, 0, 200, 0)];// 當Rect無效時返回nil
NSArray *visibleArr = [self.plainTableView indexPathsForVisibleRows];
NSArray *selectedArr = [self.plainTableView indexPathsForSelectedRows];
// 獲取Cell
UITableViewCell *cell = [self.plainTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:10 inSection:0]];// 當單元格不可見活著indexPath超出范圍時返回nil
NSArray *cellArr = [self.plainTableView visibleCells];
// 獲取UITableViewHeaderFooterView
UITableViewHeaderFooterView *headerView = [self.plainTableView headerViewForSection:0];// (iOS6)
UITableViewHeaderFooterView *footerView = [self.plainTableView footerViewForSection:0];// (iOS6)
<p>外觀 索引樣式调炬、分割線樣式语盈、單元格樣式、列表頭部尾部等等
self.plainTableView.sectionIndexMinimumDisplayRowCount = 1;// 當指定section的行數達到這個值的時候缰泡,在右側顯示該section的索引列表
self.plainTableView.sectionIndexColor = [UIColor blackColor];// section索引的文字顏色刀荒,(iOS6)
self.plainTableView.sectionIndexBackgroundColor = [UIColor grayColor];// 索引未被觸碰時的背景顏色代嗤,(iOS7)
self.plainTableView.sectionIndexTrackingBackgroundColor = [UIColor redColor];// 索引被觸碰時的背景顏色,(iOS6)
/* UITableViewCellSeparatorStyle
* UITableViewCellSeparatorStyleNone,
* UITableViewCellSeparatorStyleSingleLine,
* UITableViewCellSeparatorStyleSingleLineEtched 只有group的table可以使用該樣式
*/
self.plainTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;// 現在一般都是設為UITableViewCellSeparatorStyleNone然后自定義
self.plainTableView.separatorColor = [UIColor purpleColor];// 默認是gray
self.plainTableView.separatorEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];// 列表分隔的樣式效果缠借,(iOS8)need to do more
/*
* 啟用與iOS6干毅,客戶端可以為每一個cell注冊一個nib或class
* 如果全部重用identifiers都注冊了,使用新方法-dequeueReusableCellWithIdentifier:forIndexPath:來保證一個單元格實例返回
* 當從dequeue方法中返回實例的時候它們會重置正確的大小
*/
[self.plainTableView registerNib:[UINib nibWithNibName:@"customCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"customCell"];// 注冊自定義單元格泼返,注冊后在單元格重制方法里才能只通過Identifier就找到對應的單元格硝逢,(iOS5)
//- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
//- (void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
//- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
<p>方法
//1.刷新數據
- (void)reloadAction {
[self.plainTableView reloadData];
}
//2.刷新索引
- (void)reloadIndexTitleAction {
[self.plainTableView reloadSectionIndexTitles];
}
//3.強制定位
- (void)scrollToIndexPath {
/* UITableViewScrollPosition的枚舉
* UITableViewScrollPositionNone
* UITableViewScrollPositionTop
* UITableViewScrollPositionMiddle
* UITableViewScrollPositionBottom
*/
[self.plainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
//4.定位選中行
- (void)scrollToNearestSelectedRow {
[self.plainTableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];// 定位到indexPath最小的選中單元格的位置,多選一樣有效
}
//5.模式變換
- (void)edit:(UIButton *)sender {
sender.selected = !sender.selected;
[self.plainTableView setEditing:sender.selected animated:YES];
}
//6.選中行并定位
- (void)getPlainTableViewSelection {
NSIndexPath *indexPath = [self.plainTableView indexPathForSelectedRow];// 當有多個選中是绅喉,返回indexPath最小的那個
NSArray *indexPathArr = [self.plainTableView indexPathsForSelectedRows];// (iOS5)
[self.plainTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];// 選中
[self.plainTableView deselectRowAtIndexPath:indexPath animated:YES];// 取消選中
}
二.UITableView的四大功能
<p>添加渠鸽、刪除
/* 實現添加刪除功能
* 1:實現-tableView:canEditRowAtIndexPath: ,不實現時全部cell默認可編輯柴罐,該方法決定是否可編輯
* 2.實現-tableView:commitEditingStyle:forRowAtIndexPath:徽缚,必須實現,該方法自定義添加刪除功能
* 3.實現-tableView:editingStyleForRowAtIndexPath:革屠,不實現時為刪除樣式凿试,該方法決定編輯樣式
* 4.可以實現-tableView:willBeginEditingRowAtIndexPath:
-tableView:didEndEditingRowAtIndexPath:
兩個方法監(jiān)聽編輯動作并作相應自定義
*/
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// 可以不實現該方法,默認全部單元格都是可編輯似芝,也可在此處控制單元格是否可編輯
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// 在這里定義添加刪除功能那婉,當添加或刪除按鈕被點擊時,datasource必須提交更改党瓮,當edit動作使用UITableViewRowAction時详炬,處理動作會被取代
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableData removeObjectAtIndex:indexPath.row];
[self.plainTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
/*
* UITableViewCellEditingStyleNone
* UITableViewCellEditingStyleDelete
* UITableViewCellEditingStyleInsert
*/
return UITableViewCellEditingStyleNone;
}
<p>排序
/* 移動功能
* 1.實現-tableView:canMoveRowAtIndexPath:,不實現時全部單元格默認可移動
* 2.實現-tableView:moveRowAtIndexPath:toIndexPath:麻诀,必須實現痕寓,在該方法中定義移動功能,只有實現了該方法蝇闭,編輯模式下才顯示移動圖標
* 3.可以實現
-tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath
自定義某些特定功能呻率,不過盡量還是別實現,因為這個方法cell在移動過程中每經過一個cell就會調用一次呻引,調用地多會影響性能
* 4.可以實現
-tableView:willBeginEditingRowAtIndexPath:
-tableView:didEndEditingRowAtIndexPath:
兩個方法監(jiān)聽編輯動作并作相應自定義
*/
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// 允許某個指定行顯示復制視圖礼仗,默認情況下只有datasource實現了-tableView:moveRowAtIndexPath:toIndexPath:才顯示
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
if (sourceIndexPath != destinationIndexPath) {
id object = [tableData objectAtIndex:sourceIndexPath.row];
[tableData removeObjectAtIndex:sourceIndexPath.row];
if (destinationIndexPath.row > [tableData count]) {
[tableData addObject:object];
}
else {
[tableData insertObject:object atIndex:destinationIndexPath.row];
}
}
}
<p>索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
// 設置section標題的列表來顯示在section索引視圖上
return @[@"a",@"a",@"a",@"a",@"a",@"a"];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
// 告訴列表哪個section對應哪個索引
return index;
}
<p>復制
#pragma mark - 復制黏貼功能
// 三個方法必須都實現,缺一不可
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
// 允許長按顯示菜單逻悠,也可以作為cell長按手勢回調
NSLog(@"---------長按");
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
// 允許每一個Action
return YES;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
// 對一個給定的行告訴代表執(zhí)行復制或粘貼操作內容
if (action==@selector(copy:)) {//如果操作為復制
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard];//黏貼板
[pasteBoard setString:cell.textLabel.text];
NSLog(@"%@",pasteBoard.string);//獲得剪貼板的內容
}
}