UITableView的詳細講解

分類: ios應用開發 1338人閱讀 評論(0) 收藏 舉報

UITableView的詳細講解


1.    UITableView的初始化

 

UITableView tableview= [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; 

 [tableview setDelegate:self]; 

 [tableview setDataSource:self]; 

 [self.view addSubview: tableview]; 

 [tableview release]; 


(1)在初始化UITableView的時候必須實現UITableView的是,在.h文件中要繼承UITableViewDelegate和UITableViewDataSource,並實現3個UITableView數據源方法和設置它的delegate爲self,這個是在不直接繼承UITableViewController實現的方法。

(2) 直接在XCODE生成項目的時候繼承UITableViewController的,它會幫你自動寫好UITableView必須要實現的方法。

(3)UITableView繼承自UIScrollView。

2.    UITableView的數據源

(1)UITableView是依賴外部資源爲新表格單元填上內容的,我們稱爲數據源,這個數據源可以根據索引路徑提供表格單元格,在UITableView中,索引路徑是NSIndexPath的對象,可以選擇分段或者分行,即是我們編碼中的section和row。

(2)UITableView有三個必須實現的核心方法,分別如下:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

這個方法可以分段顯示或者單個列表顯示我們的數據。如下,左邊爲分段顯示,右邊爲單個列表顯示:

       

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

這個方法返回每個分段的行數,不同分段返回不同的行數可以用switch來做,如果是單個列表就直接返回單個你想要的函數即可。


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

這個方法是返回我們調用的每一個單元格。通過我們索引的路徑的section和row來確定。


3.    UITableView的委託方法

使用委託是爲了響應用戶的交互動作,比如下拉更新數據和選擇某一行單元格,在UITableView中有很大這種方法供我們選擇。

(1) 委託方法講解

 

//設置Section的數量

-(NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView

//設置每個section顯示的Title 

//設置每個section顯示的Title

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

{

   NSString *key = [m_titleArrayobjectAtIndex:section];

   return key;

}

 

//指定有多少個分區(Section),默認爲1 

//分區的數量

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

  return4;

}

 

//指定每個分區中有多少行,默認爲1 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

   sectionArray = [myDictionary objectForKey:[m_titleArray objectAtIndex:section]];

   return [sectionArray count];

}

 

//設置每行調用的cell 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

NSString *theSection = [m_titleArrayobjectAtIndex:indexPath.section];

//NSLog(@"theSection=%@",theSection);

    //聲明一個標識符,然後使用它請求可重用單元

 staticNSString *CellIdentifier =@"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    //如果沒有可重用單元,則創建一個

    //使用前面提到的標識符字符串手動創建一個新的表視圖單元。我們將不可避免地重複使用此處創建的單元。

if (!cell) {

cell = [[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier] autorelease];

}

    

    sectionArray = [myDictionaryobjectForKey:theSection];

NSString *singername = [sectionArrayobjectAtIndex:indexPath.row];

cell.textLabel.text = singername;

    cell.textLabel.font = [UIFontboldSystemFontOfSize:30];

cell.imageView.image = [UIImageimageNamed:[NSStringstringWithFormat:@"%@.png",singername]];//未選中cell時的圖片

    cell.imageView.highlightedImage = [UIImageimageNamed:@""];//選中cell後的圖片

cell.showsReorderControl =YES;

cell.accessoryType =UITableViewCellAccessoryDetailDisclosureButton;

return cell;

}



//設置讓UITableView行縮進

//把每行的縮進級別設置爲其行號,第0號縮進級別爲0,第1行縮進級別爲1.

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath

{

   NSUInteger row = indexPath.row;

   return row;

}

//設置cell每行間隔的高度

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

   return75;

}

//返回當前所選cell 

NSIndexPath *ip = [NSIndexPath indexPathForRow:row inSection:section];

    [_tableView selectRowAtIndexPath:ipanimated:YES scrollPosition:UITableViewScrollPositionNone];

 

//設置UITableView的SeparatorStyle 

 _tableview.separatorStyle = UITableViewCellSeparatorStyleNone;

//設置選中Cell的響應事件

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    [m_tableview deselectRowAtIndexPath:indexPath animated:YES];//選中後的反顯顏色即刻消失

}

 

//選中之前執行(阻止選中第一行)

-(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    NSLog(@"willSelectRowAtIndexPath");

    

 NSUInteger row = [indexPath row];

       if (row == 0) {

           return nil;

        }

   return indexPath;

}


//設置划動cell是否出現del按鈕

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

{

    returnYES;

}


//設置刪除時編輯狀態

-(void)tableView:(UITableView *)tableView  commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

{

 if (editingStyle ==UITableViewCellEditingStyleDelete

 {

[sectionArray removeObjectAtIndex:indexPath.row];

[m_tableview deleteRowsAtIndexPaths:[NSMutableArrayarrayWithObjects:indexPath,nilwithRowAnimation:UITableViewRowAnimationTop];

 

 }

}

 

//右側添加一個索引表

//在表視圖右側添加一個索引

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView

{

    return m_titleArray;

}


//跳到指定的row or section

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0inSection:0atScrollPosition:UITableViewScrollPositionBottom animated:NO]; 


(2)  其他

//選中cell時的顏色,在官方文檔有如下可以選擇

//選中項的風格

cell.selectionStyle = UITableViewCellSelectionStyleBlue;

typedef enum { 

    UITableViewCellSelectionStyleNone, 沒有變化

    UITableViewCellSelectionStyleBlue, 默認選中項是藍色

    UITableViewCellSelectionStyleGray 灰色

} UITableViewCellSelectionStyle 

 

//cell右邊按鈕格式

cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

typedef enum { 

    UITableViewCellAccessoryNone,                   //沒有附件

    UITableViewCellAccessoryDisclosureIndicator,    //黑色向右的箭頭

    UITableViewCellAccessoryDetailDisclosureButton, //藍色附件按鈕

    UITableViewCellAccessoryCheckmark               //複選框,支持選擇

} UITableViewCellAccessoryType 

 實現多選

- (void)tableView:(UITableView *)tableView

        didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

{

    NSLog(@"Selected section %d, cell %d", 

        [ indexPath indexAtPosition: 0 ], [ indexPath indexAtPosition: 1 ]); 

    //獲的當前選擇項

    UITableViewCell *cell = [ self.tableView cellForRowAtIndexPath: indexPath ]; 

    //顯示覆選框

    if (cell.accessoryType == UITableViewCellAccessoryNone)

        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    else

        cell.accessoryType = UITableViewCellAccessoryNone; 

}


//UITableView單元格顏色交替

由於設置單元格背景顏色只能在UITextViewDelegate代理函數willDisplayCell中有效,所以在該函數中可以設置顏色交替

//行將顯示的時候調用

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 

//方法一:

   UIColor *color = ((indexPath.row %2) ==0) ? [UIColorcolorWithRed:255.0/255green:255.0/255blue:145.0/255alpha:1] : [UIColorclearColor];  

     cell.backgroundColor = color; 

    NSLog(@"willDisplaycell");

    //方法二:

   if (indexPath.row %2 ==1

    {

        cell.backgroundColor = [UIColoryellowColor];

    }

   else

    {

        cell.backgroundColor = [UIColorredColor];

        cell.selectedBackgroundView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"cell_1.png"]];//選中cell行變圖片

    }

}

//是否加換行線

typedef enum { 

    UITableViewCellSeparatorStyleNone, 

    UITableViewCellSeparatorStyleSingleLine 

} UITableViewCellSeparatorStyle 


//改變換行線顏色

tableView.separatorColor= [UIColor blueColor]; 


4.    UITableViewCell

表中的每一行都代表一個UITableViewCell。可以使用圖像、文本還有輔助的圖標等來自定義你自己的UITableViewCell。你可以自定義你自己的cell如下模型或者像appstore那樣的。

 

UITableViewCell爲每個Cell提供了三個可以選擇的屬性,如下:

l textLabel:填寫文本

l detailTextLable:稍微詳細的副標題

l imageView:用來顯示你cell的圖片,可以通過UIImage來加載。

(1) 顯示文本: cell.text = @"Frank's Table Cell";

(2) 對齊: cell.textAlignment = UITextAlignmentLeft;

UITextAlignmentLeft 默認是左對齊

   UITextAlignmentRight 右對齊

   UITextAlignmentCenter 中對齊

(3) 字體和尺寸:

#import <UIKit/UIFont.h>

UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 18.0 ]; 

cell.font = myFont;

//系統字體

UIFont *mySystemFont = [ UIFont systemFontOfSize: 12.0 ];

UIFont *myBoldSystemFont = [ UIFont boldSystemFontOfSize: 12.0 ];

UIFont *myItalicSystemFont = [ UIFont italicSystemFontOfSize: 12.0 ];


(4) 顏色

#import <UIKit/UIColor.h>

//文本顏色

cell.textColor = [UIColor redColor];


//當前選擇cell文本的顏色

cell.selectedTextColor = [UIColor blueColor];


(5) 圖像

//從你應用程序目錄下的文件創建一個image

cell.image = [UIImage imageNamed: @"cell.png"];


//當前選中項的圖形

cell.selectedImage = [UIImage imageNamed: @"selected_cell.png" ];//選中cell後左邊圖片換


//選中後變圖片

cell.leftImageView.highlightedImage = [UIImageimageNamed:@"china_national_day-2011-hp.jpg"];


 可以修改table保準行高來適應你的圖形高度

- (id)init 

{

    self = [ super init ];

    if (self != nil) {

        self.tableView.rowHeight = 65; 

    }

    return self; 

}

你也可以爲每一個cell定義不同的高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

{

    if ([ indexPath indexAtPosition: 1 ] == 0)

        return 65.0; 

    else

        return 40.0; 

}



最後給出一個官方的demo給大家學習下,多實踐,不懂的就問下,下節課講些UITableView應用中實際會出現的問題,比如自定義啊,重用單元格,單元格的數據排序等問題。歡迎大家拍磚。

附上代碼:http://www.2cto.com/uploadfile/2011/1130/20111130025401502.zip


修改cell選中後的顏色

  UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,80)];

  cell.selectedBackgroundView = backView;

  cell.selectedBackgroundView.backgroundColor = [UIColor orangeColor];

  [backView release]; 

設置tableView偏移


// tableView內容的偏移值,第一個參數爲Y方向

 tableView.contentInset = UIEdgeInsetsMake(64,0,0,0);


修改UITableView中Delete操作的默認按鈕


默認的刪除按鈕爲Delete,如果想顯示爲刪除的話,則需要實現UITableViewDelegate中的

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath方法。


//刪除按鈕的名字

-(NSString*)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath

{

    return@"刪除按鈕";

}


或者,最簡單的方式,將plist中的Localization native development region改爲China即可。


UITableView在didSelectRowAtIndexPath實現雙擊事件的方法

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{  

//如果兩次點擊的時間間隔小於1秒,則斷定爲雙擊事件

NSUInteger curr = [[NSDate datetimeIntervalSince1970];

if (curr-taptime<1) {

[self doubleTap];

}

taptime = curr;

}


點擊變色再恢復 

[_tableView deselectRowAtIndexPath:indexPath animated:YES];


分別是摺疊狀態的tableview和展開狀態的tableview


運行效果如下,分別是摺疊狀態的tabview和展開狀態的tabview:
 

一、新建UITableViewController
 .h文件如下,包含了一個用於顯示的視圖tableview和用於表示模型數據的MutableArray.
 @interface GDXXDetailVC :UITableViewController
 <UITableViewDelegate,UITableViewDataSource,UIActionSheetDelegate>
 {
 UITableView* tableView;
 NSMutableArray* model;
 UIBarButtonItem *btnSave;
 NSString *account,*pass;
 NSArray* keys;
 }
 -(void)setModel:(NSString*)_account pass:(NSString*)_pass data:(NSArray*)_data;
 -(void)save;
 -(void)collapseOrExpand:(int)section;
 -(Boolean)isExpanded:(int)section;
 @end
.m文件如下,包含了tableview的datasource方法,和模型的處理邏輯。
#import "GDXXDetailVC.h"
@implementation GDXXDetailVC
 -(id)init{
 if(self=[super init]){
 self.title=@"工單處理";
 }
 return self;
 }
 -(void)setModel:(NSString*)_account pass:(NSString*)_pass data:(NSArray*)_data
 {
 account=_account;
 pass=_pass;
 model=[[NSMutableArray alloc]init];
 [model setArray:_data];
 [_data release];
 }
 -(void)loadView{
 self.view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
 tableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 20, 320, 480) style:UITableViewStyleGrouped];
 [self.view addSubview:tableView];
 tableView.delegate=self;
 tableView.dataSource=self;
 //這個圖片中工具欄中顯示一個保存按鈕
 btnSave= [[UIBarButtonItem alloc]
initWithTitle:@"處理"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(save)];
 self.navigationItem.rightBarButtonItem = btnSave;
 [btnSave release];
 }
 -(void)saveData{
 
}
 #pragma mark Actionsheet 委託方法
 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
 {//當ActionSheet的某個按鈕被按下時觸發
 if(buttonIndex == 0)//第一個按鈕表示保存按鈕
 {
[self performSelector:@selector(saveData)];
 }
 //解散actionSheet
 [actionSheet dismissWithClickedButtonIndex: buttonIndex animated:YES];
}
 #pragma mark ===table view dataSource method and delegate method===
 //返回分組數
 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
 return [model count];
 }
 //返回組標題
 //-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
 //{
 // NSDictionary* d=[model objectAtIndex:section];
 // if(d!=nil)
 //title=[d objectForKey:@"title"];
 // else return nil;
 //}
 //自定義section header
 - (UIView *) tableView: (UITableView *) tableView
 viewForHeaderInSection: (NSInteger) section
 {
NSString*
title=@"notitle";
 NSDictionary* d=[model objectAtIndex:section];
 if(d!=nil)
 title=[d objectForKey:@"title"];
 
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
 UIView* footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenRect.size.width, 44.0)];
 footerView.autoresizesSubviews = YES;
 footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
 footerView.userInteractionEnabled = YES;
 
footerView.hidden = NO;
 footerView.multipleTouchEnabled = NO;
 footerView.opaque = NO;
 footerView.contentMode = UIViewContentModeScaleToFill;
 
// Add the label
 UILabel* footerLabel = [[UILabel alloc] initWithFrame:CGRectMake(64, 5, 120.0, 45.0)];
 footerLabel.backgroundColor = [UIColor clearColor];
 footerLabel.opaque = NO;
 footerLabel.text = title;
 footerLabel.textColor = [UIColor blackColor];
 footerLabel.highlightedTextColor = [UIColor blueColor];
 footerLabel.font = [UIFont boldSystemFontOfSize:17];
 footerLabel.shadowColor = [UIColor whiteColor];
 footerLabel.shadowOffset = CGSizeMake(0.0, 1.0);
 [footerView addSubview: footerLabel];
 
[footerLabel release];

// Add the button
 UIButton* footerButton = [[UIButton alloc] initWithFrame:CGRectMake(12, 5, 48.0, 48.0)];
 //一開始小節是處於“摺疊狀態”,“+/-”按鈕顯示“+號”圖標
 if ([self isExpanded:section]) {//若本節轉換到“展開”狀態,需要把圖標顯示成“-”號
 [footerButton setBackgroundImage:[UIImage imageNamed:@"minus.png"] forState:UIControlStateNormal];
 }else
 [footerButton setBackgroundImage:[UIImage imageNamed:@"plus.png"] forState:UIControlStateNormal];
 [footerButton addTarget:self action:@selector(expandButtonClicked:)
 forControlEvents:UIControlEventTouchUpInside];
 footerButton.tag=section;//把節號保存到按鈕tag,以便傳遞到expandButtonClicked方法
 [footerView addSubview: footerButton];
 [footerButton release];
 // Return the footerView
 return footerView;
 }
 //當“+/-”按鈕被點擊時觸發
 -(void)expandButtonClicked:(id)sender{
 UIButton* btn=(UIButton*)sender;
 int section=btn.tag; //取得節號
 [self collapseOrExpand:section];
 
//刷新tableview
 [tableView reloadData];
 }
 //對指定的節進行“展開/摺疊”操作
 -(void)collapseOrExpand:(int)section{
 Boolean expanded=NO;
 NSMutableDictionary* d=[model objectAtIndex:section];
 //若本節model中的“expanded”屬性不爲空,則取出來
 if([d objectForKey:@"expanded"]!=nil)
 expanded=[[d objectForKey:@"expanded"]intValue];
 //若原來是摺疊的則展開,若原來是展開的則摺疊
 [d setObject:[NSNumber numberWithBool:!expanded] forKey:@"expanded"];
 }
 //返回指定節的“expanded”值
 -(Boolean)isExpanded:(int)section{
 Boolean expanded=NO;
 NSMutableDictionary* d=[model objectAtIndex:section];
 //若本節model中的“expanded”屬性不爲空,則取出來
 if([d objectForKey:@"expanded"]!=nil)
 expanded=[[d objectForKey:@"expanded"]intValue];
 return expanded;
 }
 // 設置header的高度
 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
 return 60;
 }
 //返回分組的行數
 -(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
 //對指定節進行“展開”判斷
 if (![self isExpanded:section]) {//若本節是“摺疊”的,其行數返回爲0
 return 0;
 }
 NSDictionary* d=[model objectAtIndex:section];
 return [[d objectForKey:@"items"] count];
 }
 //設置行高
 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
 return 50;
 }
 //設置每一單元格的內容
 -(UITableViewCell*)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 static NSString*
cellId=@"setcell";
 UITableViewCell* cell=(UITableViewCell*)[table dequeueReusableCellWithIdentifier:cellId];
 if(cell==nil){
 cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
 reuseIdentifier:cellId]autorelease];
 cell.selectionStyle=UITableViewCellSelectionStyleNone;
 }
 NSDictionary* items=[[model objectAtIndex:indexPath.section] objectForKey:@"items"];
 keys=[items allKeys];
 cell.textLabel.text=[items objectForKey:[keys objectAtIndex:indexPath.row]];
 cell.textLabel.font=[UIFont fontWithName:@"Arial" size:18.0];
 return cell;
 }
 //單元格選中時觸發
 -(void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
 
}
 -(void)save{
 }
 -(void)dealloc{
 [model release];
 [tableView release];
 [super dealloc];
 }
@end
二、在application的AppDelegate中實例化TableViewController
 在application方法中,構造好一個Array,把要展示的數據放到其中,然後調用TableViewController的setModel方法設置tableview的model。這個Array的結構應該是這樣的:
 NSArray 中的元素爲NSMutableDictionary(必須是Mutable,不能是NSDictionary)。每一個 NSMutableDictionary代表了一個小節的數據,包含若干key-value,其中Title爲小節名稱,expanded爲小節的展開/ 摺疊狀態,items爲小節中每一行的數據。
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
 
GDXXDetailVC* rootController=[[GDXXDetailVC alloc]init];
 NSMutableArray* items=[[NSMutableArray alloc]init];
 for (int i=1; i<10; i++) {
 NSDictionary *d=[NSDictionary dictionaryWithObjectsAndKeys:
 [NSString stringWithFormat:@"section %d item1",i],@"1",
 [NSString stringWithFormat:@"section %d item2",i],@"2",
 [NSString stringWithFormat:@"section %d item3",i],@"3",
 nil];
 NSMutableDictionary* dic=[NSMutableDictionary dictionaryWithObjectsAndKeys:
 [NSString stringWithFormat:@"title %d",i],@"title",
 d,@"items",[NSNumber numberWithBool:NO],@"expanded",
 nil];
 //[d release];
 [items addObject:dic];
 //[dic release];
}
 [rootController setModel:nil pass:nil data:items];
 //[items release];
 [rootController setTitle:@"無線應用"];
 [window addSubview:rootController.view];
 //[rootController release];
 [window makeKeyAndVisible];
 
return YES;

上一篇:UIScrollView的詳細講解下一篇:UITabBarController詳解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章