最近都在忙公司项目的项目第三个版本的迭代,其中有个频道管理功能,自己简单去实现了下,在这里只是简单的整理一下实现的过程,也希望有更好思路的人提建议,废话不多说,先看实现的效果图。
功能分析:
1、点击按钮弹出频道管理视图
2、频道分为两组,点击上面的频道跳转到指定频道,隐藏频道视图。点击下面的频道为添加频道。
3、点击编辑编辑按钮,频道按钮今日抖动状态,可以删除,长按可以拖动进行排序。
实现
看到上面的布局我开始想着用UIButton去实现,感觉有点麻烦,就想到了UICollectionView。实现起来还是比较容易的
为了代码的封装和复用,我决定用UIView来封装好,方便使用。
1、首先想到是这个频道管理视图需要两个数组来提供数据源,还有就是频道的点击事件需要传递给当前的控制器。可以使用代理来实现,但我比较懒同时习惯block,所以这里都是使用了block来实现。
/**
* 显示频道block必须实现
*/
@property (copy,nonatomic) NSMutableArray*(^showChannelsDataSource)();
/**
* 隐藏频道的block必须实现
*/
@property (copy,nonatomic) NSMutableArray*(^hideChannelDataSource)();
这两个block用来传递数据的必须实现。
后面频道的删除和添加还是比较容易的就是改变数组后,刷新。下面就简单的把长按拖动的代码贴出来
pragma mark - 长按手势处理
-
(void)longPress:(UILongPressGestureRecognizer*)longPress {
switch (longPress.state) {
case UIGestureRecognizerStateBegan:
{NSLog(@"开始长按手势"); //获取长按的点 CGPoint point = [longPress locationInView:_collectionView]; _startIndexPath = [_collectionView indexPathForItemAtPoint:point]; //获取手指所在的cell YJChannelCell *cell = (YJChannelCell*)[_collectionView cellForItemAtIndexPath:_startIndexPath]; cell.hidden = YES; //获取当前cell的截图 UIView *tempMoveCell = [cell snapshotViewAfterScreenUpdates:NO]; _tempCell = tempMoveCell; _tempCell.frame = cell.frame; _tempCell.layer.affineTransform = CGAffineTransformMakeScale(1.2, 1.2); [_collectionView addSubview:_tempCell]; _lastPoint = [longPress locationInView:_collectionView]; } break; case UIGestureRecognizerStateChanged: { CGFloat tranX = [longPress locationInView:longPress.view].x - _lastPoint.x; CGFloat tranY = [longPress locationInView:longPress.view].y - _lastPoint.y; _tempCell.center = CGPointApplyAffineTransform(_tempCell.center, CGAffineTransformMakeTranslation(tranX, tranY)); _lastPoint = [longPress locationInView:_collectionView]; for (YJChannelCell *cell in [_collectionView visibleCells]) { NSIndexPath *indexPath = [_collectionView indexPathForCell:cell]; if (indexPath == _startIndexPath || indexPath.section == 1) { continue; } //计算中心距 CGFloat spacingX = fabs(_tempCell.center.x - cell.center.x); CGFloat spacingY = fabs(_tempCell.center.y - cell.center.y); if (spacingX <= _tempCell.bounds.size.width / 2.0f && spacingY <= _tempCell.bounds.size.height / 2.0f) { _moveIndexPath = [_collectionView indexPathForCell:cell]; // 移动cell [_collectionView moveItemAtIndexPath:_startIndexPath toIndexPath:_moveIndexPath]; // 通知外面 if (self.exchangeChannelBlock) { self.exchangeChannelBlock(_startIndexPath.row,_moveIndexPath.row); } //设置移动后的起始indexPath _startIndexPath = _moveIndexPath; break; } } } break; case UIGestureRecognizerStateCancelled: case UIGestureRecognizerStateEnded: { NSLog(@"开始结束或者取消"); //获取最后的cell YJChannelCell *cell = (YJChannelCell*)[_collectionView cellForItemAtIndexPath:_startIndexPath]; [UIView animateWithDuration:0.25 animations:^{ _tempCell.center = cell.center; } completion:^(BOOL finished) { [_tempCell removeFromSuperview]; cell.hidden = NO; }]; } break; default: break;
}
}
中午休息时间有限就不详细描述实现过程了有兴趣的查看完整Demo,如果有什么错误地方希望指正,有疑问也可以问我,谢谢!