现在的位置: 首页 > 综合 > 正文

iPhone开发之UITableView入门2

2013年10月04日 ⁄ 综合 ⁄ 共 11475字 ⁄ 字号 评论关闭
iPhone开发之UITableView入门2



今天介绍一下iPhone开发的UITableView入门第二部分,之前我们已经介绍过UITableView的基本用法,今天我们要做的是自定义UITableView的每一行,实现如下图所示的效果:


UITableView的每一行都是一个UITableViewCell,我们的基本思路是创建一个继承自UITableViewCell的子类,在里面显示我们自己的内容,然后在将它插入UITableView中即可。下面我们开始吧:





1.

新建一个View-based Application,名称是Chat:






2.

下面我们创建一个继承自UITableViewCell的子类ChatViewCell:

点击右侧的Classes-->Add-->New File...,选择Objective-C class,务必要在下方的下拉列表框中选择UITableViewCell:





3.

然后我们创建对应的ChatViewCell.xib:

仍然点击右侧的Classes-->Add-->New
File...,选择Empty XIB,





4.

打开新创建的ChatViewCell.xib,从右侧的Library中拖动一个Table
View Cell到窗口中,同时修改它的Identifier为
CellIdentifier(这只是一个字符串,可以任意选取,只要和之后的相同即可,后有详述)




完成后如下:







5.

双击打开刚加入的Table View Cell,按下图加入控件:左边是一个UIImageView,右边是三个UILabel,分别表示名称,状态和留言:





要注意的是Table
View Cell的高度应该和之后代码返回的高度保持一致,后有详述。这里我调整为100

顺便说一下,在UILabel的属性框中,去掉Auto to fit前的勾号,那么如果字符串超过UILabel长度时会在最后加省略号(否则一直缩小字符串直到UILabel中可以显示





6.

修改ChatViewCell.h如下:

//
//  ChatViewCell.h
//  Chat
//
//  Created by HuTao on 8/22/12.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface ChatViewCell : UITableViewCell
{
	IBOutlet UIImageView * imageViewHead;
	IBOutlet UILabel * labelName;
	IBOutlet UILabel * labelStatus;
	IBOutlet UILabel * labelRemarks;
}



@property (retain, nonatomic) IBOutlet UIImageView * imageViewHead;
@property (retain, nonatomic) IBOutlet UILabel * labelName;
@property (retain, nonatomic) IBOutlet UILabel * labelStatus;
@property (retain, nonatomic) IBOutlet UILabel * labelRemarks;


@end




修改ChatViewCell.m如下:

//
//  ChatViewCell.m
//  Chat
//
//  Created by HuTao on 8/22/12.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#import "ChatViewCell.h"


@implementation ChatViewCell


@synthesize imageViewHead;
@synthesize labelName;
@synthesize labelStatus;
@synthesize labelRemarks;



- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
	if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
		// Initialization code
	}
	return self;
}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

	[super setSelected:selected animated:animated];

	// Configure the view for the selected state
}


- (void)dealloc
{
	[super dealloc];
	
	[imageViewHead release];
	[labelName release];
	[labelStatus release];
	[labelRemarks release];
}


@end







7.

下面是最关键的一步,首先在Chat View Cell的属性框中将Class修改为ChatViewCell:




然后在Interface Builder中关联这些控件:选择Chat
View Cell(一定不是File's Owner),按住Ctrl键,拖动到要关联的控件上,选择相应控件即可:






8.

至此自定义的UITableViewCell差不多完成了,下面我们要继续完成UITableView:

拖动一个UITableView到ChatViewController.xib中并铺满屏幕,然后在按Command+2,在属性框中分别将dataSource和delegate拖动到File's
Owner,如下图所示:




完成的结果:






9.

修改ChatViewController.h如下:

//
//  ChatViewController.h
//  Chat
//
//  Created by HuTao on 8/22/12.
//  Copyright __MyCompanyName__ 2012. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ChatViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
	NSMutableArray * dataList;
}


@property (retain, nonatomic) NSMutableArray * dataList;



-(void)addPerson:(NSString *)name status:(NSString *)status remarks:(NSString *)remarks image:(NSString *)imageName;



@end



使用UITableView的类必须要实现UITableViewDelegate和UITableViewDataSource



下面是UITableViewDelegate的所有函数

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>

@optional

// Display customization

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

// Variable height support

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

// Section header & footer information. Views are preferred over title should you decide to provide both

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;   // custom view for header. will be adjusted to default or specified header height
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;   // custom view for footer. will be adjusted to default or specified footer height

// Accessories (disclosures). 

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_0);
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;

// Selection

// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
// Called after the user changes the selection.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);

// Editing

// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);

// Controls whether the background is indented while editing.  If not implemented, the default is YES.  This is unrelated to the indentation level below.  This method only applies to grouped style table views.
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;

// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;

// Moving/reordering

// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;               

// Indentation

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath; // return 'depth' of row for hierarchies

@end





下面是UITableViewDelegate的所有函数,其中numberOfRowsInSection和cellForRowAtIndexPath是必须的。前者返回UITableView中共有多少行,后者在UITableView要显示一行时自动被调用:

@protocol UITableViewDataSource<NSObject>

@required

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

// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)

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

@optional

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;              // Default is 1 if not implemented

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;    // fixed font style. use custom view (UILabel) if you want something different
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;

// Editing

// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;

// Moving/reordering

// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

// Index

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;                                                    // return list of section titles to display in section index view (e.g. "ABCD...Z#")
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;  // tell table which section corresponds to section title/index (e.g. "B",1))

// Data manipulation - insert and delete support

// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;

// Data manipulation - reorder / moving support

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;

@end





修改ChatViewController.m如下:

//
//  ChatViewController.m
//  Chat
//
//  Created by HuTao on 8/22/12.
//  Copyright __MyCompanyName__ 2012. All rights reserved.
//

#import "ChatViewController.h"
#import "ChatViewCell.h"


@implementation ChatViewController



@synthesize dataList;



-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	return [dataList count];
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	//必须和在ChatViewCell.xib中的设置一致
	static NSString * cellIdentifier = @"CellIdentifier";
	
	//该方法第一次调用时返回nil(因为程序刚开始运行时并没有可以重用的UITableViewCell)
	ChatViewCell * cell = (ChatViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
	if (cell == nil)
	{
		//加载ChatViewCell.xib
		NSArray * array = [[NSBundle mainBundle] loadNibNamed:@"ChatViewCell" owner:self options:nil]; 
		cell = [array objectAtIndex:0];
		[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
		//[cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
	} 	
	
	NSUInteger row = [indexPath row];
	NSMutableDictionary * person = [dataList objectAtIndex:row];
	cell.labelName.text = [person objectForKey:@"name"];
	cell.labelStatus.text = [person objectForKey:@"status"];
	cell.labelRemarks.text = [person objectForKey:@"remarks"];
	[cell.imageViewHead setImage:[UIImage imageNamed:[person objectForKey:@"image"]]];
	return cell;
	
}


//UITableView行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	//和ChatViewCell.xib中的设置一致,这样才会完全重合
	return 100.0;
}


//该方法在点击UITableView的某一行前自动被调用,如果返回nil,则点击后高亮选中会消失,否则会一直存在
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ 
	return nil;
}



-(void)addPerson:(NSString *)name status:(NSString *)status remarks:(NSString *)remarks image:(NSString *)imageName
{
	NSMutableDictionary * person = [[NSMutableDictionary alloc] init];

	[person setValue:name forKey:@"name"];
	[person setValue:status forKey:@"status"];
	[person setValue:remarks forKey:@"remarks"];
	[person setValue:imageName forKey:@"image"];

	[dataList addObject:person];
}



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
	[super viewDidLoad];
	
	dataList = [[NSMutableArray alloc] init];
	
	[self addPerson:@"张三" status:@"离线" remarks:@"今天好累啊" image:@"1.jpg"];
	[self addPerson:@"李四" status:@"在线" remarks:@"明天要交作业,不写完不睡觉!" image:@"2.jpg"];
	[self addPerson:@"王五" status:@"在线" remarks:@"打Dota!" image:@"3.jpg"];
	[self addPerson:@"我是超人" status:@"忙碌" remarks:@"好无聊,想睡觉~~" image:@"4.jpg"];
	[self addPerson:@"小红" status:@"隐身" remarks:@"地球是我们共同的家园,让我们一同保卫地球" image:@"5.jpg"];
	[self addPerson:@"芳芳" status:@"离线" remarks:@"谁和我一起去看电影啊?" image:@"6.jpg"];
	[self addPerson:@"小明" status:@"隐身" remarks:@"每天都是崭新的一天,加油" image:@"7.jpg"];
	[self addPerson:@"大宝" status:@"忙碌" remarks:@"昨天钱包丢了,悲剧!" image:@"8.jpg"];
}


- (void)viewDidUnload
{
	dataList = nil;
}


- (void)dealloc
{
	[super dealloc];
	
	[dataList release];
}

@end



dataList是一个NSMutableArray数组,每个元素都是一个NSMutableDictionary,包含了name,status,remarks等键值对数据




10.

最后将所需的图片加入工程即可





运行结果如下:






点击某一项:






最后,我把完整的代码也上传上来了:

http://download.csdn.net/detail/ht916/4519260






完成!


抱歉!评论已关闭.