- iOS高级开发——CollectionView的cell中按钮的点击实现
在我刚初学iOS的时候,我就问一些大神,iOS开发中最难的哪些部分。有些人就说是自定义控件、UI和交互设计。那个时候我将信将疑,随着自己开发的深入,自己的确是深有体会。开发一款App产品,很大一部分时间是在和UI打交道。因为开发中很多功能是直接封装好的或者有现成模板可以用的,唯有UI是根据不同的App千变万化的。所以今天我们继续来研究iOS中比较高级的控件——UICollectionView,来实现cell中按钮的点击操作。该demo我已经提交到: https://github.com/chenyufeng1991/CollectionView 。里面包含了不少CollectionView的功能实现,欢迎大家下载。对于动态增加section和cell部分,可以参考: 《iOS项目开发实战——实现UICollectionView的动态增加Cell与Section》 。
(1)自定义cell
我在cell中包含了一个按钮和一个文本。自定义代码如下:
CollectionViewCell.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#
import
<uikit uikit.h=
""
>
@interface
CollectionViewCell : UICollectionViewCell
//每一个cell就是一个UIView,一个cell里面包含了一个图片和文本;
//@property(nonatomic,strong)UIView *cellView;
@property
(strong,nonatomic) UIButton *imageButton;
@property
(strong,nonatomic) UILabel *descLabel;
@end
</uikit>
|
CollectionViewCell.m:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#
import
CollectionViewCell.h
#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
@implementation
CollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [
super
initWithFrame:frame];
if
(self) {
//这里需要初始化ImageView;
self.imageButton = [[UIButton alloc] initWithFrame:CGRectMake((self.bounds.size.width -
32
) /
2
, (self.bounds.size.width -
32
) /
2
,
32
,
32
)];
self.imageButton.tag =
100
;
self.descLabel = [[UILabel alloc] initWithFrame:CGRectMake((self.bounds.size.width -
100
) /
2
, (self.bounds.size.width -
32
) /
2
+
30
,
100
,
20
)];
self.descLabel.textAlignment = NSTextAlignmentCenter;
self.descLabel.font=[UIFont systemFontOfSize:
10
];
self.descLabel.tag =
101
;
[self.contentView addSubview:self.imageButton];
[self.contentView addSubview:self.descLabel];
}
return
self;
}
@end
|
(2)为了点击这个按钮,我们要根据每一个cell来找到按钮,所以需要在
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{}方法中实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:
@CollectionCell
forIndexPath:indexPath];
// cell.imageView.image = [UIImage imageNamed:[[self.dataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]];
//设置设备图片按钮的点击事件;
// UIButton *deviceImageButton = (UIButton*)[cell viewWithTag:100];
// [deviceImageButton addTarget:self action:@selector(deviceButtonPressed:row:) forControlEvents:UIControlEventTouchUpInside];
//找到每一个按钮;
UIButton *deviceImageButton = cell.imageButton;
[deviceImageButton addTarget:self action:
@selector
(deviceButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
//给每一个cell加边框;
cell.layer.borderColor = [UIColor grayColor].CGColor;
cell.layer.borderWidth =
0.3
;
[cell.imageButton setBackgroundImage:[UIImage imageNamed:
@0
] forState:UIControlStateNormal];
cell.descLabel.text = @文本;
return
cell;
}
|
(3)实现按钮的点击。这里是重点,如果这里我们想直接对按钮进行操作,是无法完成的。必须要注意按钮和cell之间的层级关系。如果大家使用了storyboard或者nib,可以打开查看层级关系,由于我这里的cell是代码生成的,无法直观的给大家看。但是它们的层级关系是:Cell-->ContentView-->button. 所以注意的是:我们必须找到该button对应的cell,才能完全确定该button的section和row。所以要注意代码中的两个:superview方法。该按钮的实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
|
- (
void
)deviceButtonPressed:(id)sender{
UIView *v = [sender superview];
//获取父类view
CollectionViewCell *cell = (CollectionViewCell *)[v superview];
//获取cell
NSIndexPath *indexpath = [self.collectionView indexPathForCell:cell];
//获取cell对应的indexpath;
NSLog(@设备图片按钮被点击:%ld %ld,(
long
)indexpath.section,(
long
)indexpath.row);
}
|
(4)运行程序,我们可以发现点击按钮可以获得响应,并打印出该按钮的indexPath.section和indexPath.row。点击按钮和点击cell是彼此独立,没有任何影响的,可以分别进行响应事件的处理。
总结:通过实际开发我们可以发现,TableView和CollectionView实在是太像了,两者毕竟都继承自ScrollView,CollectionView其实就是TableView的扩展。现在往往就是看着TableView的某些效果或者代码,然后试图去CollectionView上实现,反之亦可。就像看着OC写Swift或者看着Swift写OC一样。 如果有熟悉Android的同学也会发现,今天我们讲到的TableView、CollectionView关系就像是Android中ListView和RecycleView的关系一样。只有融会贯通,我们才会随心所欲实现自己想要的效果。让我们一起学习,一起进步吧。