如何将 UICollectionViewCell 从一个 UICollectionView 拖到另一个 UICollectionView?
Posted
技术标签:
【中文标题】如何将 UICollectionViewCell 从一个 UICollectionView 拖到另一个 UICollectionView?【英文标题】:How can I drag a UICollectionViewCell from one UICollectionView to another UICollectionView? 【发布时间】:2013-06-21 14:38:46 【问题描述】:我正在制作一个 iPad 应用程序。在此应用程序的一个页面上,左侧有一个 UICollectionView,右侧有另一个 UICollectionView。每个 UICollectionView 都是一列宽。
我想要的功能如下: 左侧的每个 UICollectionViewCell 都应该能够拖到右侧的 UICollectionView 上。如果这是不可能的,那么至少应该能够将一个 UICollectionViewCell 拖出左侧 UICollectionView,然后我会处理让它出现在右侧 UICollectionView 中。
这个功能可行吗?如果是这样,我将如何实施它?
【问题讨论】:
【参考方案1】:您可能希望将长按手势识别器附加到两个 collectionView 的公共超级视图。拖动操作由长按触发,整个事务在该识别器中处理。因为平移手势用于滚动集合视图,所以在尝试使用平移识别器时会遇到问题。
关键是手势识别器需要附加COMMON superview,所有点和矩形都转换到superview的坐标系。
这不是确切的代码(这会从 CV 转移到另一个视图),但过程类似(注意:我试图删除一些与您的应用程序无关的代码,所以我可能搞砸了在这个过程中有些东西——但这个概念是成立的):
- (void) processLongPress:(UILongPressGestureRecognizer *)sender
if (sender.state == UIGestureRecognizerStateChanged)
if (!dragView)
return;
CGPoint location = [sender locationInView:self.view];
CGPoint translation;
translation.x = location.x - dragViewStartLocation.x;
translation.y = location.y - dragViewStartLocation.y;
CGAffineTransform theTransform = dragView.transform;
theTransform.tx = translation.x;
theTransform.ty = translation.y;
dragView.transform = theTransform;
[self.view bringSubviewToFront:dragView];
return;
if (sender.state == UIGestureRecognizerStateBegan)
// if point gives a valid collectionView indexPath we are doing a long press on a picture item to begin a drag
// & drop operation.
CGPoint point = [sender locationInView:collectionView];
dragViewIndexPath = [collectionView indexPathForItemAtPoint:point];
if (dragViewIndexPath) // i.e., selected item in collection view.
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:dragViewIndexPath];
dragView = [cell.contentView viewWithTag:cell.tag];
[dragView removeFromSuperview];
[self.view addSubview:dragView];
dragView.center = [collectionView convertPoint:point toView:self.view];
dragViewStartLocation = dragView.center;
[self.view bringSubviewToFront:dragView];
return;
if (sender.state == UIGestureRecognizerStateEnded)
if (dragView)
dragView.center = CGPointMake(dragView.center.x + dragView.transform.tx, dragView.center.y + dragView.transform.ty);
CGAffineTransform theTransform = dragView.transform;
theTransform.tx = 0.0f;
theTransform.ty = 0.0f;
UIView *dropTarget = [self mapDisplayModeToReceiverView]; // get drop target
CGRect convertedTargetFrame = [self.view convertRect:dropTarget.frame fromView:dropTarget.superview];
if (CGRectContainsPoint(convertedTargetFrame, dragView.center)) // if so, then drop it.
ImageWithAttachedLabel *i = (ImageWithAttachedLabel *) dragView;
[speakStrings addObject:[i.labelText stringByAppendingString:@". "]];
UserData *uData = (UserData *)i.userDataObject;
UIImage *image = [[UIImage alloc] initWithData:uData.image];
CGRect newFrame = CGRectMake(0.0f, 0.0f, 140.0f, 140.0f);
ImageWithAttachedLabel *newImage = [[ImageWithAttachedLabel alloc] initWithFrame:newFrame withImage:image withLabel:uData.itemName];
newImage.tag = RECEIVERVIEW_MAGIC_NUMBER;
[self.view addSubview:newImage];
newImage.center = [receiverView convertPoint:dropTarget.center toView:self.view];
[UIView animateWithDuration:0.35f animations:^ newImage.transform = CGAffineTransformMakeScale(1.15f, 1.15f); newImage.transform = CGAffineTransformIdentity;
completion:^(BOOL finished) if (finished)
[newImage removeFromSuperview];
newImage.frame = newFrame;
[dropTarget addSubview:newImage];
[dragView removeFromSuperview];
dragView=nil;
];
else
[dragView removeFromSuperview];
dragView = nil;
[self reloadData];
return;
【讨论】:
你好@regularExpression,你的代码中的dragView是什么? 嗨,dragView 只是一个指向正在拖动的 UIView 的指针。它设置为手势识别器“StateBegan”代码中被拖动的视图:dragView = [cell.contentView viewWithTag:cell.tag] 在这种情况下,视图是集合视图中单元格的内容,但它确实可以是任何观点。【参考方案2】:实际上无法将一个单元格从一个集合“传递”到另一个集合,但您可以执行以下操作:
1) 一旦您检测到用户拖动了另一个集合中的单元格,请从第一个集合中删除该单元格(我们称之为集合 1)。您也许可以使用漂亮的淡入淡出动画来使单元格消失。
2) 向第二个表格添加一个带有漂亮动画的单元格(请参阅 UICollectionView 和 UICollectionViewLayout 方法和委托方法)。
【讨论】:
谢谢,这很有道理。我怎样才能实现具有可拖动单元格?我需要使用LXReorderableCollectionViewFlowLayout 之类的东西吗?或者有没有更简单的资源可以指点我?谢谢。 您可以使用此 LXReorderableCollectionViewFlowLayout,它还允许您使用手势对单元格进行排序,或者在手势开始时将 UIPanGestureRecognizer 添加到您的集合中(UICollectionView 有一种方法),然后当用户拖动单元格时相应地移动它。当手势结束或取消时,您可以检查单元格的位置并采取相应措施。 再次感谢,第二个选项听起来正是我正在寻找的,也很容易实现。 不客气。由于我注意到您对社区很陌生,因此我只想让您注意到您可以“接受”答案,并且随着您的声誉增长,您还将获得一些特权。您将首先得到的一个是“赞成”好的答案或“反对”不好的答案。如果您喜欢,请随时接受我的回答;)以上是关于如何将 UICollectionViewCell 从一个 UICollectionView 拖到另一个 UICollectionView?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UICollectionViewCell 高度设置为视图(屏幕)高度的 90%?
如何将导航栏移到 UICollectionViewCell 之外?
如何将 UIView 约束为 UICollectionViewCell
如何将 UICollectionViewCell 放在前面?