玩转iOS开发:iOS 11 新特性《UICollectionView的拖拽》

文章分享至我的个人技术博客: cainrun.github.io/15102983446…


还记得在WWDC 2017的时候, 苹果爸爸展示的拖拽功能是多么的牛逼, 实现了可夸应用的数据分享.

如果你有看过之前的, 那么你应该有一个基础的认识, 如果没有也没关系, 因为你正在看着这篇文章.

这里我们会用一个针对iPad Pro 10.5英寸的小项目进行演示.

转载声明:如需要转载该文章, 请联系作者, 并且注明出处, 以及不能擅自修改本文.

工程的配置

这里我打算使用Storyboard来作为主开发的工具, 为了省下过多的布局代码.

玩转iOS开发:iOS 11 新特性《UICollectionView的拖拽》1

这是模仿一个顾客去买水果的场景, 这里面的布局也不算难, 主要逻辑:

  • 主容器控制器嵌入两个比较小的视图控制器, 通过ListController分别管理.
  • ListController主要是显示一个UICollectionView, 而我们拖拽也是在ListController里实现的.

简单的写了一下数据模型, 并且控制一下对应的数据源, 我们就可以看到简单的界面了:

玩转iOS开发:iOS 11 新特性《UICollectionView的拖拽》2

配置拖拽的功能

配置UICollectionView其实是非常容易的, 我们只需要将一个声明UICollectionViewDragDelegate代理的实例赋值给UICollectionView, 然后再实现一个方法就可以了.

接下来这里, 我们设置一下拖拽的代理, 并且实现必要的拖拽代理方法:

self.collectionView.dragDelegate = self;
    self.collectionView.dropDelegate = self;
#pragma mark - Collection View Drag Delegate
- (NSArray<UIDragItem *> *)collectionView:(UICollectionView *)collectionView
             itemsForBeginningDragSession:(id<UIDragSession>)session
                              atIndexPath:(NSIndexPath *)indexPath {

    NSItemProvider *itemProvider = [[NSItemProvider alloc] init];

    UIDragItem *item = [[UIDragItem alloc] initWithItemProvider:itemProvider];

    return @[item];
}

这样子我们就可以看到长按CollectionView时会有长按拖拽效果了:

玩转iOS开发:iOS 11 新特性《UICollectionView的拖拽》3

配置拖放的"放"效果

拖拽效果有了, 但问题来了, 当我们拖拽到另一个UICollectionView松手时, 会发现并不能将数据拖拽过去, 其实是我们并没有配置UICollectionViewDropDelegate代理, 这个和刚刚的配置方法一样, 这里就不多说了.

首先我们来实现一个方法:

- (BOOL)collectionView:(UICollectionView *)collectionView
  canHandleDropSession:(id<UIDropSession>)session {

    return session.localDragSession != nil ? YES : NO;
}

这个可选方法是在咨询你会否愿意处理拖放, 我们可以通过实现这个方法来限制从同一个应用发起的拖放会话.

这个限制是通过UIDropSession中的localDragSession进行限制, 如果为YES, 则表示接受拖放, 如果为NO, 就表示不接受.

讲完这个之后, 我们来看看UICollectionViewDropDelegate唯一一个要实现的方法, 这个方法要有相应, 是根据上面的那个方法是返回YES还是返回NO来判断的:

- (void)collectionView:(UICollectionView *)collectionView
performDropWithCoordinator:(id<UICollectionViewDropCoordinator>)coordinator {

}

然后我们配置好UICollectionViewDropDelegate的代理对象, 再试试拖拽效果, 机会发现拖到隔壁的UICollectionView的右上角会有一个绿色的加好:

玩转iOS开发:iOS 11 新特性《UICollectionView的拖拽》4

配置你的意图

我们在UICollectionView里拖动一个对象的时候, UICollectionView会咨询我们的意图, 然后根据我们不同的配置, 就会做出不同的反应.

这里我们要分成两个部分, 第一个部分是一个叫做UIDropOperation:

typedef NS_ENUM(NSUInteger, UIDropOperation) {
    UIDropOperationCancel    = 0,
    UIDropOperationForbidden = 1,
    UIDropOperationCopy      = 2,
    UIDropOperationMove      = 3,
} API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
  • UIDropOperationCancel: 表示取消拖动操作, 如果是使用这个枚举的话, 会导致-dropInteraction:performDrop:这个方法不被调用.
  • UIDropOperationForbidden: 表示该操作被禁止, 如果你是使用这个枚举的话, 在拖拽时会显示一个

相关推荐