我正在学习iOS11新的API拖放,但我有一些问题。
我有两个CollectionView,它们共享相同的类型(
数据实体
)数据源数组的。一个用于拖动,另一个用于拖放。这意味着我要拖动包含数据的项(
数据实体
)从一个集合视图到另一个集合视图。
那我有问题了
[-(id<UICollectionDropDelegate>)collectionView:performDropWithCoordinator:]
. 我无法获取数据(
数据实体
)在我的第一个collectionView中通过,因为
-[UIDragSession loadObjectsOfClass:completion:]
未调用completionBlock。但是,如果我将其他类(如UIImage.class或NSString.class)设置为参数
loadObjectsOfClass:
将调用完成块,但它不是兼容类,因此没有返回对象。
源代码
拖动集合视图
- (NSArray<UIDragItem *> *)collectionView:(UICollectionView *)collectionView itemsForBeginningDragSession:(id<UIDragSession>)session atIndexPath:(NSIndexPath *)indexPath {
DataEntity* entity = self.entities[indexPath.row];
UIDragItem* item = [[UIDragItem alloc] initWithItemProvider:[[NSItemProvider alloc] initWithObject:entity]];
return @[item];
}
删除集合视图
- (void)collectionView:(UICollectionView *)collectionView performDropWithCoordinator:(id<UICollectionViewDropCoordinator>)coordinator {
NSIndexPath* destinationIndexPath = coordinator.destinationIndexPath;
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView performBatchUpdates:^{
[coordinator.session loadObjectsOfClass:DataEntity.class completion:^(NSArray<__kindof id<NSItemProviderReading>> * _Nonnull objects) {
[objects enumerateObjectsUsingBlock:^(__kindof id<NSItemProviderReading> _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self.mutableEntities insertObject:(DataEntity*)obj atIndex:destinationIndexPath.row];
[self.collectionView insertItemsAtIndexPaths:@[destinationIndexPath]];
}];
}];
} completion:nil];
});
}
- (BOOL)collectionView:(UICollectionView *)collectionView canHandleDropSession:(id<UIDropSession>)session {
BOOL test = [session canLoadObjectsOfClass:DataEntity.class];
return test;
}
数据实体
- (NSProgress *)loadDataWithTypeIdentifier:(NSString *)typeIdentifier forItemProviderCompletionHandler:(void (^)(NSData * _Nullable, NSError * _Nullable))completionHandler {
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:self];
completionHandler(data, nil);
return nil;
}
+ (NSArray<NSString *> *)writableTypeIdentifiersForItemProvider {
NSString* identifier = NSStringFromClass(self.class);
return @[identifier];
}
+ (NSArray<NSString *> *)readableTypeIdentifiersForItemProvider {
NSString* identifier = NSStringFromClass(self.class);
return @[identifier];
}
+ (nullable instancetype)objectWithItemProviderData:(nonnull NSData *)data typeIdentifier:(nonnull NSString *)typeIdentifier error:(NSError * _Nullable __autoreleasing * _Nullable)outError {
DataEntity* entity = [NSKeyedUnarchiver unarchiveObjectWithData:data];
return entity;
}
编辑
好的,我发现了一些东西。
首先,如果我删除
dispatch_async(dispatch_get_main_queue())
,我将得到一个错误
未协调的选择器-[DataEntity encodeWithCoder:]
. 这是第二件事,我忘了
数据实体
符合
N编码
协议
现在的新问题是,为什么我不能打电话
-[UIDragSession loadObjectsOfClass:完成:]
在里面
dispatch\u main\u队列
闭包,还是不调用其完成块?