- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习 iOS11 新 API 拖放,但我有一些问题。我有两个共享相同类型 (DataEntity) 的 dataSource 数组的 collectionView。一个用于拖动,另一个用于放下。这意味着我想将包含数据 (DataEntity) 的项目从一个 collectionView 拖到另一个。
然后我在[-(id<UICollectionDropDelegate>)collectionView:performDropWithCoordinator:]
中有问题.我无法获取在我的第一个 collectionView 中传递的数据 (DataEntity),因为 -[UIDragSession loadObjectsOfClass:completion:]
completionBlock 没有被调用。但是,如果我将其他类(例如 UIImage.class 或 NSString.class)设置为参数 loadObjectsOfClass:
将调用完成 block ,但它不是兼容的类,因此没有返回对象。
源代码
拖拽collectionView
- (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];
}
放下collectionView
- (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]; // It's YES
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())
,我会得到一个错误unrecoginized selector -[DataEntity encodeWithCoder:]。这是第二件事,我忘记让 DataEntity 符合 NSCoding 协议(protocol)。
现在新的问题是,为什么我不能调用 -[UIDragSession loadObjectsOfClass:completion:]
在 dispatch_main_queue 闭包中,或者它的完成 block 不会被调用?
最佳答案
这一切都与异步代码执行的基本原则有关。在您的 collectionView:performDropWithCoordinator:
实现中,这段代码是错误的:
dispatch_async(dispatch_get_main_queue(), ^{
[coordinator.session loadObjectsOfClass: // ...
当您调用 dispatch_async
时,您允许对 collectionView:performDropWithCoordinator:
的调用返回 — 它结束了!但是您在继续加载数据之前就这样做了。因此,在 您有机会获取数据之前,丢弃立即结束并且 session 消失。当我们到达 loadObjectsOfClass
时,不再有数据; session 已经结束。
事实上,我敢打赌此时的 session
是 nil
。发送到 nil
对象的代码什么也不做;这就是为什么您的 objectWithItemProviderData
和完成处理程序永远不会被调用的原因。
关于ios - -[UIDragSession loadObjectsOfClass :completion:] completionBlock not being called,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47880026/
我正在学习 iOS11 新 API 拖放,但我有一些问题。我有两个共享相同类型 (DataEntity) 的 dataSource 数组的 collectionView。一个用于拖动,另一个用于放下。
我是一名优秀的程序员,十分优秀!