這篇文章主要講的表格的操作包括:標記行、移動行、刪除行、插入行。
這次就不從頭建立工程了,在http://www.oschina.net/code/snippet_164134_9876下載工程。這個工程就是最簡單的產生一個表格並向其中寫入數據。用Xcode 4.2打開它,在這個工程基礎上實現以上操作。
1、標記行
這裏講的標記行指的是單擊此行,可以實現在此行右邊出現一個勾,如下圖所示:
爲了實現標記功能,在ViewController.m中@end之前添加代碼:
#pragma mark - #pragma mark Table Delegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *oneCell = [tableView cellForRowAtIndexPath: indexPath]; if (oneCell.accessoryType == UITableViewCellAccessoryNone) { oneCell.accessoryType = UITableViewCellAccessoryCheckmark; } else oneCell.accessoryType = UITableViewCellAccessoryNone; [tableView deselectRowAtIndexPath:indexPath animated:YES]; }
該代碼實現:單擊某行時,若此行未被標記,則標記此行;若此行已經被標記,則取消標記。
運行效果如上圖。
上面的代碼實際上就是修改某行的accessoryType屬性,這個屬性可以設爲四個常量:
UITableViewCellAccessoryCheckmark UITableViewCellAccessoryDetailDisclosureButton UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryNone
效果依次如下圖所示:
UITableViewCellAccessoryCheckmark UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryNone
注意,上面第二張圖片中的藍色圓圈不僅僅是一個圖標,還是一個控件,點擊它可以觸發事件,在上一篇博客《iOS開發16:使用Navigation Controller切換視圖》使用過。
2、移動行
想要實現移動或者刪除行這樣的操作,需要啓動表格的編輯模式。使用的是setEditing:animated:方法。
2.1 打開ViewController.xib,將其中的表格控件映射成Outlet到ViewController.h,名稱爲myTableView。
2.2 打開ViewController.m,在viewDidLoad方法最後添加代碼:
//啓動表格的編輯模式 [self.myTableView setEditing:YES animated:YES];
2.3 在@end之前添加代碼:
//打開編輯模式後,默認情況下每行左邊會出現紅的刪除按鈕,這個方法就是關閉這些按鈕的 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleNone; } //這個方法用來告訴表格 這一行是否可以移動 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } //這個方法就是執行移動操作的 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *) sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { NSUInteger fromRow = [sourceIndexPath row]; NSUInteger toRow = [destinationIndexPath row]; id object = [list objectAtIndex:fromRow]; [list removeObjectAtIndex:fromRow]; [list insertObject:object atIndex:toRow]; }
editingStyleForRowAtIndexPath這個方法中用到了常量UITableViewCellEditingStyleNone,它表示不可編輯,這裏的編輯指的是刪除和插入。表示表格行的編輯模式的常量有:
UITableViewCellEditingStyleDelete UITableViewCellEditingStyleInsert UITableViewCellEditingStyleNone
顧名思義,第一個表示刪除,第二個表示插入,第三個表示不可編輯。
若將editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleNone依次換成上面三個值,則它們運行的效果依次如下圖所示:
2.4 運行,從下圖可以看到實現了行的移動:
但是也會發現,現在無法對每行進行標記了。這說明,在編輯模式下,無法選擇行,從而didSelectRowAtIndexPath這個方法不會執行。
3、刪除行
從第2步過來,實現刪除某行,其實比較簡單了。
3.1將editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleNone修改成UITableViewCellEditingStyleDelete。
3.2 在@end之前添加代碼:
//這個方法根據參數editingStyle是UITableViewCellEditingStyleDelete //還是UITableViewCellEditingStyleDelete執行刪除或者插入 - (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger row = [indexPath row]; if (editingStyle == UITableViewCellEditingStyleDelete) { [self.list removeObjectAtIndex:row]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } }
在這個方法中又出現了一個常量:UITableViewRowAnimationAutomatic,它表示刪除時的效果,類似的常量還有:
UITableViewRowAnimationAutomatic UITableViewRowAnimationTop UITableViewRowAnimationBottom UITableViewRowAnimationLeft UITableViewRowAnimationRight UITableViewRowAnimationMiddle UITableViewRowAnimationFade UITableViewRowAnimationNone
它們的效果就不一一介紹了,可以在實際使用時試試。
3.3 運行,看看效果:
剛運行時顯示如左邊的圖片,點擊某一行左邊的圓圈圖標,會顯示如中間圖片所示。然後點擊Delegate按鈕,那一行就會被刪除掉,如右邊的那張圖片所示,它顯示的是刪除時的效果。
4、插入行
這個與刪除行類似。
4.1 首先將editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleDelete修改成UITableViewCellEditingStyleInsert。
4.2在3.2添加的方法中添加代碼:
else { //我們實現的是在所選行的位置插入一行,因此直接使用了參數indexPath NSArray *insertIndexPaths = [NSArray arrayWithObjects:indexPath,nil]; //同樣,將數據加到list中,用的row [self.list insertObject:@"新添加的行" atIndex:row]; [tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight]; }
上面的代碼中也可以不用insertRowsAtIndexPaths方法,而直接使用[tableView reloadData];語句,但是這樣就沒有添加的效果了。
4.3 好了,運行一下:
剛運行時如上面左圖所示,單擊了某個加號後,新的一行就從右邊飛進來了,因爲在insertRowsAtIndexPaths中用了參數UITableViewRowAnimationRight。
UITableView每個cell之間的默認分割線如何去掉
很簡單,只需要
tableView.separatorStyle = NO;
UITableView
-、建立 UITableView
DataTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 420)];
[DataTable setDelegate:self];
[DataTable setDataSource:self];
[self.view addSubview:DataTable];
[DataTable release];
二、UITableView各Method說明
//Section總數
- (NSArray *)sectionIndexTitlesForTableView:(UITableView*)tableView{
return TitleData;
}
// Section Titles
//每個section顯示的標題
- (NSString *)tableView:(UITableView *)tableViewtitleForHeaderInSection:(NSInteger)section{
return @"";
}
//指定有多少個分區(Section),默認爲1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 4;
}
//指定每個分區中有多少行,默認爲1
- (NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section{
}
//繪製Cell
-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier =@"SimpleTableIdentifier";
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:
SimpleTableIdentifier];
if (cell ==nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: SimpleTableIdentifier]
autorelease];
}
cell.imageView.image=image;//未選cell時的圖片
cell.imageView.highlightedImage=highlightImage;//選中cell後的圖片
cell.text=//.....
return cell;
}
//行縮進
-(NSInteger)tableView:(UITableView *)tableViewindentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
return row;
}
//改變行的高度
- (CGFloat)tableView:(UITableView *)tableViewheightForRowAtIndexPath:(NSIndexPath *)indexPath{
return40;
}
//定位
[TopicsTable setContentOffset:CGPointMake(0, promiseNum * 44 +Chapter * 20)];
//返回當前所選cell
NSIndexPath *ip = [NSIndexPath indexPathForRow:rowinSection:section];
[TopicsTable selectRowAtIndexPath:ip animated:YESscrollPosition:UITableViewScrollPositionNone];
[tableViewsetSeparatorStyle:UITableViewCellSelectionStyleNone];
//選中Cell響應事件
- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPathanimated:YES];//選中後的反顯顏色即刻消失
}
//判斷選中的行(阻止選中第一行)
-(NSIndexPath *)tableView:(UITableView *)tableViewwillSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUIntegerrow = [indexPath row];
if (row ==0)
return nil;
returnindexPath;
}
//划動cell是否出現del按鈕
- (BOOL)tableView:(UITableView *)tableViewcanEditRowAtIndexPath:(NSIndexPath *)indexPath {
}
//編輯狀態
- (void)tableView:(UITableView *)tableViewcommitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
[topicsTable setContentSize:CGSizeMake(0,controller.promiseNum *44)];
//右側添加一個索引表
- (NSArray *)sectionIndexTitlesForTableView:(UITableView*)tableView{
}
//返回Section標題內容
- (NSString *)tableView:(UITableView *)tableViewtitleForHeaderInSection:(NSInteger)section{
}
//自定義划動時del按鈕內容
- (NSString *)tableView:(UITableView *)tableView
titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath*)indexPath
//跳到指的row or section
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0inSection:0] atScrollPosition:UITableViewScrollPositionBottomanimated:NO];
三、在UITableViewCell上建立UILable多行顯示
- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {
staticNSString *CellIdentifier =@"Cell";
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:CellIdentifier];
if (cell ==nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZeroreuseIdentifier:CellIdentifier] autorelease];
UILabel *Datalabel = [[UILabelalloc] initWithFrame:CGRectMake(10, 0, 320, 44)];
[Datalabel setTag:100];
Datalabel.autoresizingMask =UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[cell.contentViewaddSubview:Datalabel];
[Datalabel release];
}
UILabel *Datalabel = (UILabel *)[cell.contentViewviewWithTag:100];
[Datalabel setFont:[UIFontboldSystemFontOfSize:18]];
Datalabel.text = [data.DataArrayobjectAtIndex:indexPath.row];
cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator;
returncell;
}
//選中cell時的顏色
typedef enum {
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray
} UITableViewCellSelectionStyle
//cell右邊按鈕格式
typedef enum {UITableViewCellAccessoryDisclosureIndicator, // regular chevron. doesn't track
UITableViewCellAccessoryDetailDisclosureButton, // blue button w/chevron. tracks
UITableViewCellAccessoryCheckmark // checkmark. doesn't track
} UITableViewCellAccessoryType
//是否加換行線
typedef enum {
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine
} UITableViewCellSeparatorStyle
//改變換行線顏色
tableView.separatorColor =[UIColor blueColor];
解決自定義UITableViewCell在瀏覽中出現數據行重複的問題
原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://ddkangfu.blog.51cto.com/311989/
我在寫一個App的時候自定義了一個UITableViewCell,但是這個UITableView在運行的時候出現了每6行數據就循環重複顯示的問題,而直接使用cell.textLabel.text顯示是沒有這個問題,以下是我實現的代碼。
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- NSInteger section = [indexPath section];
- NSInteger row = [indexPath row];
- UITableViewCell *cell;
- switch (section)
- {
- case 0:
- //do something.
- case 1:
- cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
- if (cell == nil)
- {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];
- //Image
- UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 14.0f, 45.0f, 50.0f)];
- image.backgroundColor = [UIColor clearColor];
- image.image = [UIImage imageNamed:@"folder.png"];
- [cell.contentView addSubview:image];
- [image release];
- //Label
- UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(45.0f, 6.0f, 214.0f, 50.0f)];
- titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
- NSLog(@"%@ -- %d", titleLabel.text, row);
- titleLabel.textAlignment = UITextAlignmentLeft;
- titleLabel.numberOfLines = 3;
- titleLabel.tag = 201;
- titleLabel.font = [UIFont boldSystemFontOfSize:14];
- [cell.contentView addSubview:titleLabel];
- [titleLabel release];
- }
- cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
- break;
- }
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- return cell;
- }
google了一下,目前已有的解決方案是將
- cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
替換成
- cell = [tableView cellForRowAtIndexPath:indexPath];
或者
- cell = nil;
這們做的目的去掉Cell的重用機制,但是這種方法都會在後臺隨着表格滾動一直在創建cell,通過上面源代碼中Label定義裏那句NSLog在控制檯輸出就可以看到,雖然會自動回收內存,但肯定也會給系統帶來不小開銷,所以不到萬一得以還是不會用的。
還有一種解決方案是自己定義Cell數組,在tableView:tableView cellForRowAtIndexPath:中進設置要顯示的cell,這是手工維護cell的一種方式,對大數據量的情況肯定是不適用的,不過也能算得上是一種思路吧,可以參考一下。其代碼如下:
- //在構造函數裏定義cell數組
- for(int i = 0; i < 31; i ++)
- {
- static NSString *MyBookMarkIdentifier = @"CityMangerCell";
- cityCell[i] = [[CityMangerCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyBookMarkIdentifier initIndex:i];
- }
- //使用它
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- if((0 <= indexPath.row) && (indexPath.row < 31))
- return cityCell[indexPath.row];
- return nil;
- }
後來我仔細分析了一下程序,找到了問題所在:
原因是在if (cell == nil)判斷內部不應該對其label進行賦值,即不使用這句:
- titleLabel.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
正確的做法應該是在if (cell == nil){}判斷後面進行賦值。即
- if (cell == nil)
- {
- ....
- }
- UILabel *l1 = (UILabel *)[cell.contentView viewWithTag: 201];
- l1.text = (NSString *)[(NSArray *)[self.categoryArray objectAtIndex:1] objectAtIndex:row];
分析原因如下:
UITableView中被實例化的cell個數由屏高和每個cell的高度決定,因爲我的cell高度設置爲80,一屏只能 顯示6個Cell(只有6個cell被實例化),也就是隻有這6個cell纔會執行if (cell == nil){}中的代碼,從第6行往後的cell都是重用的這6個cell,也就是說從第7行開始將不會執行if (cell = nil){}中的代碼,當UITableView需要繪製第7行cell的時候,會取得第1個cell進行重用,如果我們不把原來第1行cell中的 Label內容進行修改,那麼第7行將完全顯示第1行中的內容,所以纔會在第6行之後開始出現數據重複的情況。
現在我將Label內容設置的代碼放到if (cell == nil){}之後,它將會對每一個被重用的cell的Label進行設定,也就不會再出現cell內容重複的現象。
希望這個問題的解決過程會對大家有所幫助。這個問題解決出自 “一葉障目” 博客,請務必保留此出處http://ddkangfu.blog.51cto.com/311989/465557
- 1.系統默認的顏色設置
- //無色
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- //藍色
- cell.selectionStyle = UITableViewCellSelectionStyleBlue;
- //灰色
- cell.selectionStyle = UITableViewCellSelectionStyleGray;
2.自定義顏色和背景設置
改變UITableViewCell選中時背景色:
UIColor *color = [[UIColoralloc]initWithRed:0.0green:0.0blue:0.0alpha:1];//通過RGB來定義自己的顏色
- cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:cell.frame] autorelease];
- cell.selectedBackgroundView.backgroundColor = [UIColor xxxxxx];
3自定義UITableViewCell選中時背景
- cell.selectedBackgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellart.png"]] autorelease];
- 還有字體顏色
- cell.textLabel.highlightedTextColor = [UIColor xxxcolor]; [cell.textLabel setTextColor:color];//設置cell的字體的顏色
4.設置tableViewCell間的分割線的顏色
[theTableView setSeparatorColor:[UIColor xxxx ]];
5、設置cell中字體的顏色
// Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if(0 == indexPath.row) { cell.textLabel.textColor = ...; cell.textLabel.highlightedTextColor = ...; } ... }