私はiOS11の新しいAPIドラッグアンドドロップを学んでいますが、いくつか質問があります。 dataSource配列の同じタイプ(DataEntity)を共有する2つのcollectionViewがあります。 1つはドラッグ用で、もう1つはドロップ用です。つまり、データを含むアイテム(DataEntity)を1つのコレクションビューから別のコレクションビューにドラッグしたいということです。- [UIDragSession loadObjectsOfClass:completion:] completionBlockが呼び出されない
私は[-(id<UICollectionDropDelegate>)collectionView:performDropWithCoordinator:]
に質問があります。 -[UIDragSession loadObjectsOfClass:completion:]
completionBlockが呼び出されていないため、最初のcollectionViewで渡されたデータ(DataEntity)を取得できません。ただし、他のクラス(UIImage.classやNSString.classなど)をパラメータに設定すると、補完ブロックが呼び出されますが、互換クラスではないため、戻りオブジェクトはありません。
ソースコード
ドラッグ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;
}
編集
[OK]をクリックします。 最初にdispatch_async(dispatch_get_main_queue())
を削除すると、未確認のセレクタ - [DataEntity encodeWithCoder:]が表示されます。それは第二の事です、私は忘れてしまいますDataEntityはに従います。NSCodingプロトコル。
今、新しい質問は、私がをdispatch_main_queueクロージャーにコールできないか、その完了ブロックが呼び出されないということです。
あなたの 'objectWithItemProviderData'は呼び出されていますか? – matt
@matt番号 'readableTypeIdentifiersForItemProvider'と 'writableTypeIdentifiersForItemProvider'が呼び出されます。 'loadDataWithTypeIdentifier'と 'objectWithItemProviderData'は呼び出されません。 – Tepmnthar