看了好多有关自定义UITableViewCell的文章,在我看来这货在iOS开发的过程中,需要用到的几率是相当的大嘛。而UITabelView在我个人看来又是iOS控件中的一个大Bug,用的不好就会出现各种不明就里的错误。
工程最终效果如下:
第一步,建立一个Single View Application,然后打开storyBoard,删去原来的ViewController,从控件列表中拖入一个UITableViewController.选中UITableView中的Cell,自定义它的高度为60(后面我们会发现这样做是达不到目的的)。如图:
第二步,向Cell中添加需要自定义的控件,这次先添加一个UIImageView作为头像显示,一个UILabel作为网名,一个UILabel作为备注名,一个UILabel作为个性签名。拖动设置UIIamgeView的宽度,三个UILabel的位置及宽度,还有字体显示的大小。这些都可以在后面用代码实现。如图:
第三步,新建一个继承自UITableViewCell的类,命名为customCell。在custom.h中建立相应的IBOutlet,并与storyBoard里UITableView中自定义的Cell对应的控件建立关联。这里有一点需要特别注意:将自定义的Cell与custom.h相关联。如图:
这里会有一个warning,如下图,这是因为每个Cell都应该有个标识,Identifier.解决办法是给它一个定义:
第四步,建立一个plist文件,在里面添加内容,添加时点击右键,选择Add row,如图:
好了,现在可以开始写代码了,首先是custom.h:
#import <UIKit/UIKit.h>
@interface customCell : UITableViewCell
{
}
@property(nonatomic,retain) IBOutlet UIImageView *headerImageView;
@property(nonatomic,retain) IBOutlet UILabel *nameLabel;
@property(nonatomic,retain) IBOutlet UILabel *noteNameLabel;
@property(nonatomic,retain) IBOutlet UILabel *signatureLabel;
@property(nonatomic,retain) UIImage *headerImage;
@property(nonatomic,retain) NSString *name;
@property(nonatomic,retain) NSString *noteName;
@property(nonatomic,retain) NSString *signature;
@end
然后在custom.m文件中,重写set函数,这样就可以为Cell中自定义的控件赋值了。
#import "customCell.h"
@implementation customCell
@synthesize headerImageView,nameLabel,noteNameLabel,signatureLabel;
@synthesize headerImage,name,noteName,sigature;
/*
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
NSLog(@"1234567");//测试一下,这个函数其实是没有用到的
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}*/
-(void)setHeaderImage:(UIImage *)headerimage
{
headerImage=[headerimage copy];
UIImage* image=[self scaleFromImage:headerImage toSize:self.headerImageView.frame.size];
//调整图片的大小,是适应UIImageView
self.imageView.highlighted=YES;
self.headerImageView.image=image;
}
-(void)setName:(NSString *)name1
{
name=[name1 copy];
self.nameLabel.text=name;
self.nameLabel.font=[UIFont systemFontOfSize:15];//设置字体大小
}
-(void)setNoteName:(NSString *)notename
{
noteName=[notename copy];
self.noteNameLabel.text=noteName;
self.noteNameLabel.font=[UIFont systemFontOfSize:14];
}
-(void)setSigature:(NSString *)signature1
{
signature=[signature1 copy];
self.signatureLabel.text=signature;
self.signatureLabel.font=[UIFont systemFontOfSize:13];
}
- (UIImage *) scaleFromImage: (UIImage *) image toSize: (CGSize) size//改变图片大小
{
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
接下来实现customCellViewController.h文件:
#import <UIKit/UIKit.h> #import "customCell.h" @interface customCellViewController : UITableViewController { //如前面一篇文章里提到的,直接继承自UITableViewController的时候是不用添加UITableViewDelegate和 UITableViewDataSource的。 //@在两括号之间添加的属性类似于C++中的private,是不能被继承的 } @property (strong, nonatomic) NSArray *dataList; @property (strong, nonatomic) NSArray *imageList; @end然后是.m文件:
#import "customCellViewController.h"
@interface customCellViewController ()
@end
@implementation customCellViewController
@synthesize dataList,imageList;
/*
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
NSLog(@"87654321");//同样,这个函数其实并没有用到
return self;
}
*/
- (void)viewDidLoad
{
[super viewDidLoad];
//读取本地plist文件
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"userInfo" withExtension:@"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
NSMutableArray *tmpDataArray = [[NSMutableArray alloc] init];
NSMutableArray *tmpImageArray = [[NSMutableArray alloc] init];
for (int i=0; i<[dictionary count]; i++) {
NSString *key = [[NSString alloc] initWithFormat:@"%i", i];
NSDictionary *tmpDic = [dictionary objectForKey:key];
[tmpDataArray addObject:tmpDic];
NSString *imageUrl = [[NSString alloc] initWithFormat:@"image%i.jpg", i+1];
UIImage *image = [UIImage imageNamed:imageUrl];
[tmpImageArray addObject:image];
}
self.dataList=[tmpDataArray copy];
self.imageList=[tmpImageArray copy];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
-(void)viewWillAppear:(BOOL)animated
{
[self.tableView reloadData];//每次载入都重新下载数据
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell=[[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//@Cell的重用机制是一个很复杂也很容易的出错的货,后面有时间慢慢分析一下,这次就先略过了。
NSInteger row=indexPath.row;
NSDictionary *rowData=[dataList objectAtIndex:row];
cell.headerImage=[imageList objectAtIndex:row];
cell.name=[rowData valueForKey:@"name"];
cell.noteName=[rowData valueForKey:@"noteName"];
cell.sigature=[rowData valueForKey:@"signature"];
cell.selectionStyle=UITableViewCellSelectionStyleNone;//cell不可选
return cell;
}
#pragma mark - Table view delegate
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;//返回自定义cell的高度
}
//@如果注释掉这个函数,我们会发现,之前在storyBoard中设定的Cell的高度其实并没有执行。所以,这个函数不得不自己实现
@end
好了,现在可以运行了,效果如下:
有一点需要注意的地方,这一点我没怎么想通,就是在实现自定义Cell时,自定义的Cell必须是在用以显示数据的UITableView中。就像我不能再建一个继承自UITableViewController的类,然后在这个类里面调用customCell.h来显示自定义的Cell,貌似这样是不可以的。这点有懂的大侠们,求指点啊~~~