如何在触摸时旋转图像并将图像拖动到另一个图像上

Posted

技术标签:

【中文标题】如何在触摸时旋转图像并将图像拖动到另一个图像上【英文标题】:How to rotate an Image on touch and Drag image over another Image 【发布时间】:2014-09-12 07:36:01 【问题描述】:

我正在开发一个应用程序,我需要一个包含许多图像的图库。我想要做的是当用户点击/单击任何图像时,它应该将该图像旋转 90 度,如果用户将任何图像拖动到任何其他图像的顶部,那么这些图像应该切换它们的位置(或者我们可以说交换的地方)。

解释:

A B C

D E F

假设上面是我画廊的图像,所以如果用户将图像 A 拖到图像 E 的顶部,那么画廊应该看起来像这样

E B C

D A F

我正在使用 UICollectionView 制作我的画廊。这是我到目前为止所做的。

- (void)viewDidLoad

    [super viewDidLoad];

    self.imageArray = [NSArray arrayWithObjects:@"angry_birds_cake.jpg", @"creme_brelee.jpg", @"egg_benedict.jpg", @"full_breakfast.jpg", @"green_tea.jpg", @"ham_and_cheese_panini.jpg", nil];

    [self.collectionView registerClass:[ClosetsCell class] forCellWithReuseIdentifier:@"ClosetsCell"];
    [self.collectionView setPagingEnabled:YES];

    // Configure layout
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    [flowLayout setItemSize:CGSizeMake(100, 100)];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    [self.collectionView setCollectionViewLayout:flowLayout];


-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
        return [self.imageArray count];


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 

    // Setup cell identifier
    static NSString *cellIdentifier = @"ClosetsCell";

    ClosetsCell *cell = (ClosetsCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    cell.imageView.image = [UIImage imageNamed:[self.imageArray objectAtIndex:indexPath.row]];
    cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"checked.png"]];

    // Return the cell
    return cell;



-(CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section

    return 1;


-(CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

    return 4;


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

    static NSString *cellIdentifier = @"ClosetsCell";

    ClosetsCell *cell = (ClosetsCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    printf("Selected View index=%d",indexPath.row);

    cell.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);


但我认为 CGAffineTransformMakeRotation 不适用于我的案例。

【问题讨论】:

【参考方案1】:

就轮换而言,您可以通过以下方式实现:

CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI / 2.0);

/* If you want an animation
[UIView beginAnimations: @"" context: NULL];
[UIView setAnimationDuration: 0.3];
*/

cell.imageView.transform = CGAffineTransformConcat(cell.transform, rotation);

/*[UIView commitAnimations];*/

CGAffineTransformMakeRotation 参数是角度,可让您以您想要的方式旋转。 M_PI / 2.0 表示左旋转,M_PI / -2.0 右旋转,角度为 0 将使您回到纵向。如果您的实现想要在单击单元格时来回旋转,您可以实现如下所示:

CGAffineTransform leftRotation = CGAffineTransformMakeRotation(M_PI / 2.0);
CGAffineTransform portraitRotation = CGAffineTransformMakeRotation(0.0);

if (CGAffineTransformEqualToTransform(leftRotation, cell.imageView.transform))
    cell.imageView.transform = CGAffineTransformConcat(cell.transform, portraitRotation);

else if (CGAffineTransformEqualToTransform(portraitRotation, cell.imageView.transform))
    cell.imageView.transform = CGAffineTransformConcat(cell.transform, leftRotation);

现在对于您的第二个问题,切换单元格,我从未使用过 UICollectionViews,但我认为您应该在拖动结束时查看 - (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath(通过检查拖动开始和拖动结束的 indexPath)。

根据Apple documentation,这是用于处理 UI 操作的方法。

使用此方法重新组织现有数据项。你可能会这样做 当您重新排列数据源对象中的项目或 响应用户与集合视图的交互。

【讨论】:

我看到你已经编辑了这一行 cell.imageView.transform = CGAffineTransformConcat(cell.view.transform, rotation); 但我的 customCell 没有任何名为 view 的对象,所以我尝试了这个 cell.imageView.transform = CGAffineTransformConcat(cell.imageView.transform, rotation); 但仍然没有运气。 你说得对,我的错,我编辑了!该行是cell.imageView.transform = CGAffineTransformConcat(cell.transform, rotation); 我自己做了一些测试,它有效。 ClosetsCell *cell = (ClosetsCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 替换为ClosetsCell *cell = (ClosetsCell *)[collectionView cellForItemAtIndexPath:indexPath];。由于单元格已经可见,您可以使用cellForItem 获取它,无需实例化一个新单元格!它有效。 谢谢!!它现在可以工作,我已经赞成你的答案,但是有一个问题是我们应该如何调整它,以便每次单击图像时它都可以旋转。现在它只旋转一次。 你想让它旋转回原来的状态?

以上是关于如何在触摸时旋转图像并将图像拖动到另一个图像上的主要内容,如果未能解决你的问题,请参考以下文章

如何从商店动态获取图像到旋转木马煎茶触摸 2

Android:通过拖动图像的特定部分来旋转图像

仅在触摸图像时拖动图像

如何检测 UI 图像上的触摸?

在旋转视图上调整拖动手势

iPhone iOS:如何在图像背景上动态移动/调整图像大小?