草庐IT

ios - UICollectionView 单元格的水平重新排序

coder 2024-01-18 原文

我有一个水平滚动的 UICollectionView。每个单元格对应数组中的一个对象(货币代码)。我想要的是能够通过拖放手势对单元格重新排序。

我找到了一个 tutorial对于 UITableView 并尝试过,但是当我按住并拖动一个单元格时,它只会垂直移动,当我将手指移到屏幕边缘时它不会滚动。这是一个gif .

我想要发生的是让单元格水平移动,而不是垂直移动,并让 Collection View 在到达屏幕边缘时滚动。我将如何实现这一目标?

这是我现在拥有的:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(longPressGestureRecognised:)];
[self.collectionView addGestureRecognizer: longPress];


-(IBAction) longPressGestureRecognised:(id)sender
{
UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
UIGestureRecognizerState state = longPress.state;

CGPoint location = [longPress locationInView: self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint: location];

static UIView *snapshot = nil;
static NSIndexPath *sourceIndexPath = nil;

switch (state) {
    case UIGestureRecognizerStateBegan: {
        if (indexPath) {
            sourceIndexPath = indexPath;

            UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath: indexPath];

            // Take a snapshot of the selected item using helper method.
            snapshot = [self customSnapshotFromView: cell];

            // Add the snapshot as subview, centered at cell's centre.
            __block CGPoint centre = cell.center;
            snapshot.center = centre;
            snapshot.alpha = 0.0;
            [self.collectionView addSubview: snapshot];
            [UIView animateWithDuration: 0.25 animations:^{

                // Offset for gesture location.
                centre.y = location.y;
                snapshot.center = centre;
                snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
                snapshot.alpha = 0.98;

                // Fade out.
                cell.alpha = 0.0;

            } completion: ^(BOOL finished) {
                cell.hidden = YES;
            }];
        }
        break;
    }

    case UIGestureRecognizerStateChanged: {
        CGPoint centre = snapshot.center;
        centre.y = location.y;
        snapshot.center = centre;

        // Is destination valid and is it different from source?
        if (indexPath && ![indexPath isEqual: sourceIndexPath]) {
            // Update data source.
            [currencyArray exchangeObjectAtIndex: indexPath.item withObjectAtIndex:sourceIndexPath.item];

            // Move the items.
            [self.collectionView moveItemAtIndexPath: sourceIndexPath toIndexPath: indexPath];

            // And update source so it is in sync with UI changes.
            sourceIndexPath = indexPath;
        }
        break;
    }

    default: {
        // Clean up.
        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath: sourceIndexPath];
        cell.hidden = NO;
        cell.alpha = 0.0;
        [UIView animateWithDuration: 0.25 animations: ^{

            snapshot.center = cell.center;
            snapshot.transform = CGAffineTransformIdentity;
            snapshot.alpha = 0.0;

            // Undo fade out.
            cell.alpha = 1.0;

        }completion: ^(BOOL finished) {

            sourceIndexPath = nil;
            [snapshot removeFromSuperview];
            snapshot = nil;

        }];
        break;
    }
}
}


-(UIView *) customSnapshotFromView:(UIView *)inputView
{
// Make an image from the input view.
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, NO, 0);
[inputView.layer renderInContext: UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Create an image view.
UIView *snapshot = [[UIImageView alloc] initWithImage: image];
snapshot.layer.masksToBounds = NO;
snapshot.layer.cornerRadius = 0.0;
snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
snapshot.layer.shadowRadius = 5.0;
snapshot.layer.shadowOpacity = 0.4;

return snapshot;
}

编辑: 我想通了。这是代码:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(handleLongGesture:)];
[self.collectionView addGestureRecognizer: longPress];

-(IBAction) handleLongGesture: (id)sender {
UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;

CGPoint location = [longPress locationInView: self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint: location];

switch (longPress.state) {
    case UIGestureRecognizerStateBegan:
        [self.collectionView beginInteractiveMovementForItemAtIndexPath: indexPath];
        NSLog(@"Gesture began");
        break;

    case UIGestureRecognizerStateChanged:
        [self.collectionView updateInteractiveMovementTargetPosition: [longPress locationInView: longPress.view]];
        NSLog(@"Gesture state changed");
        break;

    case UIGestureRecognizerStateEnded:
        [self.collectionView endInteractiveMovement];
        NSLog(@"Gesture state ended");
        break;

    default:
        [self.collectionView cancelInteractiveMovement];
        NSLog(@"Gesture cancelled");
        break;
    }
}

最佳答案

在 UIGestureRecognizerStateChanged 中: 更改这行代码

        CGPoint centre = snapshot.center;
        centre.x = location.x;
        snapshot.center = centre;

centre.y 返回 y 轴拖动

将其更改为center.x用于x轴拖动

关于ios - UICollectionView 单元格的水平重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37437614/

有关ios - UICollectionView 单元格的水平重新排序的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  6. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - 单元测试文件 I/O 方法 - 2

    我对单元测试还是比较陌生。我用Ruby编写了一个类,它接受一个文件,在该文件中搜索给定的Regex模式,替换它,然后将更改保存回文件。我希望能够为此方法编写单元测试,但我不知道我将如何去做。有人能告诉我我们如何对处理文件i/o的方法进行单元测试吗? 最佳答案 看看这个HowdoIunit-testsavingfiletothedisk?基本上这个想法是一样的,文件系统是你的类的依赖。所以引入一个可以在你的单元测试中模拟的角色/接口(interface)(这样你在单元测试时就没有依赖性);角色中的方法应该是您从文件系统中需要的所有东西

  9. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  10. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

随机推荐