在项目中,我们经常会使用UITableView,但是tableView中的cell格式又不一定每次都是一样的,所以我们需要自己实现我们自定义的cell,而自定义cell的方式也由很多,我们先采取用Xib的方式。
1.通过xib创建一个cell,并且通过tag来获取cell上的其他子元素,这种方式会产生很多的tag,让tag都暴漏在控制器中,不方便管理,而且viewWithTag性能低下,每次使用的时候,会遍历所有tag。 部分代码:
- // tag比较多不容易管理
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- static NSString * ID=@"CELL";
-
- UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
- if (cell==nil) {
- // cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:ID];
- //通过xib文件加载cell
- cell= [[[NSBundle mainBundle] loadNibNamed:@"BookCell" owner:nil options:nil] lastObject];
-
- //绑定监听器
- UIButton *cool=(UIButton *)[cell viewWithTag:3];
- [cool addTarget:self action:@selector(coolectBook:event:) forControlEvents:UIControlEventTouchUpInside];
- }
-
- //覆盖shuj
- Book *book=self.books[indexPath.row];
-
- //拿出第一个cell
- UILabel *nameLable=(UILabel *)[cell viewWithTag:1];
- nameLable.text=book.name;
-
- UILabel *priceLable=(UILabel *)[cell viewWithTag:2];
-
- priceLable.text=[NSString stringWithFormat:@"¥%.1f",book.price];
- NSLog(@"%p",cell);
-
- return cell;
通过触控点的位置获取所在行
- //根据位置获取所在的行
- -(void)coolectBook:(UIButton *)btn event:(UIEvent *)event //包含所有的触摸点
- {
- UITableView *tableView=(UITableView *)self.view;
- NSSet *touches = [event allTouches]; //包含所有的uitouch 单点触控就只有一个uitouch
-
- UITouch *touch= [touches anyObject];
- //获取触摸点在uitableVIEW上的位置
- CGPoint p=[touch locationInView:tableView];
- NSIndexPath *path= [tableView indexPathForRowAtPoint:p];
- Book *book=self.books[path.row];
- NSLog(@"row--%@",book.name);
-
- }
2.利用loadNibNamed加载xib文件的时候把控制器传入owner,让xib的file's owner的custom class为控制器,也就是控制器充当监听器,这样控制器就可以监听到自定义cell的方法,这样做,耦合度比较高,不利于维护和扩展,自定义的cell只能被一个控制器使用。
部分代码:
- NSArray *objs= [[NSBundle mainBundle] loadNibNamed:@"BookCell" owner:self options:nil] ;
3.我们自己以面向对象的方式,把关于自定义cell的所有的元素都封装在一个类里面,写一个子类继承自UITableViewCell,并把xib创建的cell的custom class改为子类的名称,这样我们加载xib生成的cell对象就是我们的子类对象。
封装的子类cell
- #import <UIKit/UIKit.h>
-
- /*
-
- 把一个cell上的元素封装在一个整体
- 只提供get方法
- */
-
- @interface BookCell : UITableViewCell
- @property (weak, nonatomic,readonly) IBOutlet UILabel *nameLable;
- @property (weak, nonatomic,readonly) IBOutlet UILabel *priceLable;
- @property (weak, nonatomic,readonly) IBOutlet UIButton *BuyBtn;
-
- @end
注意:这里我们要使用readonly让外界只能访问我们内部的组件。
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- static NSString * ID=@"CELL";
-
- BookCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
- if (cell==nil) {
- // cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:ID];
- //通过xib文件加载cell
- NSArray *objs= [[NSBundle mainBundle] loadNibNamed:@"BookCell" owner:self options:nil] ;
-
- NSLog(@"%@",[objs lastObject]);
-
- cell=[objs lastObject];
- //绑定监听器
-
-
- //为子类的btn对象绑定事件
- [cell.BuyBtn addTarget:self action:@selector(buyBook) forControlEvents:UIControlEventTouchUpInside];
- }
-
- //覆盖数据
- Book *book=self.books[indexPath.row];
-
- cell.nameLable.text=book.name;
- cell.priceLable.text=[NSString stringWithFormat:@"%.1f",book.price];
-
- return cell;
- }
通过这种方式,我们自定义的cell很灵活,就像一个插件一样,如果其他地方要使用,只用导入我们的.h文件就可以了。
4.纯代码添加自定义的cell,子类会重写父类的initWithStyle方法用来初始化cell的样式 .h文件
- #import <UIKit/UIKit.h>
-
- @interface MsgCell : UITableViewCell
- @property(nonatomic,weak,readonly) UIImageView * icon;
- @property(nonatomic,weak,readonly) UIButton * messageBtn;
- @end
- #import "MsgCell.h"
-
- @implementation MsgCell
-
- - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if (self) {
- UIImageView *icon=[[UIImageView alloc]init];
- icon.frame=CGRectMake(10, 10, 50, 50);
- [self.contentView addSubview:icon];
- //[self addSubview:icon];
- _icon=icon;
-
- UIButton *btn=[[UIButton alloc]init];
- btn.frame=CGRectMake(80, 10, 200, 60);
- [btn setBackgroundImage:[UIImage imageNamed:@"chatfrom_bg_focused.png"] forState:UIControlStateHighlighted];
- [btn setBackgroundImage:[UIImage imageNamed:@"chatfrom_bg_normal.png"] forState:UIControlStateNormal];
- [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- [self.contentView addSubview:btn];
- _messageBtn=btn;
- }
- return self;
- }
- @end
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- static NSString *ID=@"cell";
- MsgCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
- if (cell==nil) {
- cell=[[MsgCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
- }
-
- cell.icon.image=[UIImage imageNamed:@"1.jpg"];
- [cell.messageBtn setTitle:@"dfgdfgdfg" forState:UIControlStateNormal];
-
- return cell;
- }
|