在开发中灵活使用cell可以省去不少麻烦, 这里介绍如何让cell随着偏移量动态改变大小的效果.期间使用过刷新固定cell, 和操作cell的坐标, 整体做起来效果不佳而且非常麻烦, 这里使用间接方法实现操作。
- 看一下效果先
看一下代码
//设置cell的上下内边距
self.tableV.contentInset = UIEdgeInsetsMake(SCellHeight, 0, self.view.frame.size.height - BCellHeight, 0);
- 这里要注意tableview的初始化,需要对内边距进行这是,这时候tableview的偏移量会是-SCellHeight的大小。里面的数据需要自己多打印才能准确计算,这里不做过多说明
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//在滑动过程中获取当前显示的所有cell, 调用偏移量的计算方法
[[self.tableV visibleCells] enumerateObjectsUsingBlock:^(MoveCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//cell偏移设置
[obj cellOffsetOnTabelView:self.tableV];
}];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell第一次出现时调用计算偏移量
MoveCell *getCell = (MoveCell *)cell;
[getCell cellOffsetOnTabelView:tableView];
}
- 在vc控制器里在移动cell的触发方法中与cell将要出现的方法里需要对cell的位置进行判断,对满足条件的cell进行偏移量进行设置。其他正常的正常
- 接下来进入到自定义的cell中,这里为MoveCell看一下初始化中添加了什么
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//取消cell点击的效果
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, SCellHeight)];
[self.contentView addSubview:self.imageV];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, SCellHeight)];
self.label.numberOfLines = 0;
self.label.font = [UIFont systemFontOfSize:FontSize];
self.label.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.label];
self.label.text = @"改变字体大小";
//添加点击方法
UITapGestureRecognizer *tapG = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.imageV addGestureRecognizer:tapG];
}
return self;
}
- (void)tapAction:(UIGestureRecognizer *)gestur
{
NSLog(@"点击了%ld", gestur.view.tag);
}
- (void)cellOffsetOnTabelView:(UITableView *)tabelView
{
CGFloat currentLocation = tabelView.contentOffset.y + BCellHeight;
//如果超出规定的位置以 ->“上”
if (self.frame.origin.y < tabelView.contentOffset.y + BCellHeight - SCellHeight) {
self.imageV.height = BCellHeight;
self.imageV.y = - (BCellHeight - SCellHeight);
self.label.font = [UIFont systemFontOfSize:FontSize * 4];
}else if (self.frame.origin.y <= currentLocation && self.frame.origin.y >= tabelView.contentOffset.y) {
//cell开始进入规定的位置
//通过绝对值 取出移动的Y值
CGFloat moveY = ABS(self.frame.origin.y - currentLocation) / SCellHeight * (BCellHeight - SCellHeight);
[[self superview] bringSubviewToFront:self];
//移动的值 + cell固定高度
self.imageV.height = SCellHeight + moveY;
self.label.height = SCellHeight + moveY;
//设置偏移量Y值
self.label.y = - moveY;
self.imageV.y = - moveY;
//通过move改变字体的大小 倍数 与起始变化位置自己定义 这里以最大值4倍计算
if (BCellHeight - SCellHeight > moveY && moveY > 20) {
self.label.font = [UIFont systemFontOfSize:FontSize * moveY / 20];
} else if (moveY <= 20)
{
self.label.font = [UIFont systemFontOfSize:FontSize];
} else {
self.label.font = [UIFont systemFontOfSize:FontSize * 4];
}
}else{
//超出规定的位置以 ->“下”
self.imageV.height = SCellHeight;
self.imageV.y = 0;
self.label.font = [UIFont systemFontOfSize:FontSize];
}
}
这里这个方法取消cell的点击效果,因为改变坐标的原因cell的点击方法并不准确,用手势来替代点击方法,需要注意的就是点击时候需要知道点击的是第几个要为imageview添加tag值,建议在返回cell中,当然也可以在cell将要出现的方法中
- 这里强调一下,因为本身
self.view.frame.origin.x
self.view.frame.origin.y
self.view.frame.size.height
self.view.frame.size.width
这些属性本身是属于可读不可改的,所以这里给view添加一个类目可以方便修改尺寸与计算
- (void)cellOffsetOnTabelView:(UITableView *)tabelView
- 主要的计算都在这个方法,首先要知道你所控制的cell什么时候达到你的条件,
本文设计的是始终保持一个完整的最大cell保持在屏幕上,从开始移动到移动结束路程为 2 * (BCellHeight - SCellHeight)那么如何判断达到这个条件可以用cell的frame中的y,y的值是固定一直保持不变的,这一个固定量就是计算的关键了。这里设置的是第二个cell的y为界限, 上限是cell距离最上端距离最大值与最小值的差。这里的计算需要自己多打印几次进行比较就会明白。还有一点计算移动的距离同样要进行计算,对于计算题就不进行详细说明。大家可以参考本文的方式来调整到自己的预计效果!
这里主要提供一个类似效果的思路,具体实践可根据个人要求进行改进。如果有人发现更简便的方法可以交流,希望可以帮助到你!
附上Demo仅供参考!