Skip to content

Commit 74e8915

Browse files
committed
fix(ios): reorder works with dinamic size cells
also added commented code for drag/drop
1 parent d511698 commit 74e8915

File tree

1 file changed

+158
-6
lines changed

1 file changed

+158
-6
lines changed

src/collectionview/index.ios.ts

Lines changed: 158 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export class CollectionView extends CollectionViewBase {
9090
draggingStartDelta: [number, number];
9191

9292
nativeViewProtected: UICollectionView;
93+
// dragDelegate: UICollectionViewDragDelegateImpl;
94+
// dropDelegate: UICollectionViewDropDelegateImpl;
9395

9496
constructor() {
9597
super();
@@ -102,7 +104,8 @@ export class CollectionView extends CollectionViewBase {
102104
if (CollectionViewBase.layoutStyles[this.layoutStyle]) {
103105
layout = this._layout = CollectionViewBase.layoutStyles[this.layoutStyle].createLayout(this);
104106
} else {
105-
layout = this._layout = UICollectionViewFlowLayout.alloc().init();
107+
// layout = this._layout = UICollectionViewFlowLayoutImpl.initWithOwner(this);
108+
layout = this._layout = UICollectionViewFlowLayout.new();
106109
}
107110
if (layout instanceof UICollectionViewFlowLayout) {
108111
layout.minimumLineSpacing = 0;
@@ -130,10 +133,13 @@ export class CollectionView extends CollectionViewBase {
130133
public initNativeView() {
131134
super.initNativeView();
132135

133-
const nativeView = this.nativeView;
136+
const nativeView = this.nativeViewProtected;
134137
this._dataSource = CollectionViewDataSource.initWithOwner(this);
135138
nativeView.dataSource = this._dataSource;
136139

140+
// this.dragDelegate = nativeView.dragDelegate = UICollectionViewDragDelegateImpl.initWithOwner(this);
141+
// this.dropDelegate = nativeView.dropDelegate = UICollectionViewDropDelegateImpl.initWithOwner(this);
142+
137143
// delegate will be set in first onLayout because we need computed _effectiveColWidth and _effectiveRowHeight
138144

139145
this._measureCellMap = new Map<string, { cell: CollectionViewCell; view: View }>();
@@ -154,8 +160,10 @@ export class CollectionView extends CollectionViewBase {
154160
if (Trace.isEnabled()) {
155161
CLog(CLogTypes.log, 'disposeNativeView');
156162
}
157-
const nativeView = this.nativeView;
163+
const nativeView = this.nativeViewProtected;
158164
nativeView.delegate = null;
165+
// nativeView.dragDelegate = null;
166+
// nativeView.dropDelegate = null;
159167
this._delegate = null;
160168
nativeView.dataSource = null;
161169
this._dataSource = null;
@@ -459,6 +467,14 @@ export class CollectionView extends CollectionViewBase {
459467
return this.orientation === 'horizontal';
460468
}
461469

470+
public clearCachedSize(...indexes:number[]) {
471+
const sizes: NSMutableArray<NSValue> = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
472+
if (sizes) {
473+
indexes.forEach(index=>sizes.replaceObjectAtIndexWithObject(index, NSValue.valueWithCGSize(CGSizeZero)))
474+
475+
}
476+
}
477+
462478
public onSourceCollectionChanged(event: ChangedData<any>) {
463479
const view = this.nativeViewProtected;
464480
if (!view || this._dataUpdatesSuspended || !this._lastLayoutKey) {
@@ -472,7 +488,7 @@ export class CollectionView extends CollectionViewBase {
472488
// this.clearCellSize();
473489

474490
const sizes: NSMutableArray<NSValue> = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
475-
const performBatchUpdatesCompletion = (c) => {
491+
const performBatchUpdatesCompletion = (c) => {
476492
// if we are not "presented" (viewController hidden) then performBatchUpdatesCompletion would crash
477493
const viewIsLoaded = !!this.page?.viewController ? !!this.page.viewController.view.window : true;
478494
if (viewIsLoaded) {
@@ -1146,6 +1162,24 @@ class CollectionViewCell extends UICollectionViewCell {
11461162
}
11471163
}
11481164

1165+
@NativeClass
1166+
class UICollectionViewFlowLayoutImpl extends UICollectionViewFlowLayout {
1167+
_owner: WeakRef<CollectionView>;
1168+
1169+
static initWithOwner(owner: CollectionView) {
1170+
const layout = UICollectionViewFlowLayoutImpl.new() as UICollectionViewFlowLayoutImpl;
1171+
layout._owner = new WeakRef(owner);
1172+
return layout;
1173+
}
1174+
invalidationContextForInteractivelyMovingItemsWithTargetPositionPreviousIndexPathsPreviousPosition(targetIndexPaths: NSArray<NSIndexPath> , targetPosition: CGPoint, previousIndexPaths: NSArray<NSIndexPath>, previousPosition: CGPoint): UICollectionViewLayoutInvalidationContext {
1175+
const owner = this._owner?.get()
1176+
if (owner && targetIndexPaths.count) {
1177+
owner.clearCachedSize(targetIndexPaths.objectAtIndex(0).row, previousIndexPaths.objectAtIndex(0).row)
1178+
// owner.clearCachedSize(previousIndexPaths.objectAtIndex(0).row)
1179+
}
1180+
return super.invalidationContextForInteractivelyMovingItemsWithTargetPositionPreviousIndexPathsPreviousPosition(targetIndexPaths, targetPosition, previousIndexPaths, previousPosition);
1181+
}
1182+
}
11491183
@NativeClass
11501184
class CollectionViewDataSource extends NSObject implements UICollectionViewDataSource {
11511185
_owner: WeakRef<CollectionView>;
@@ -1184,7 +1218,7 @@ class CollectionViewDataSource extends NSObject implements UICollectionViewDataS
11841218
if (owner) {
11851219
owner.reorderStartingRow = sourceIndexPath.row;
11861220
owner.reorderEndingRow = destinationIndexPath.row;
1187-
owner._reorderItemInSource(sourceIndexPath.row, destinationIndexPath.row, false);
1221+
// owner._reorderItemInSource(sourceIndexPath.row, destinationIndexPath.row, false);
11881222
}
11891223
}
11901224
collectionViewTargetIndexPathForMoveFromItemAtIndexPathToProposedIndexPath?(collectionView: UICollectionView, originalIndexPath: NSIndexPath, proposedIndexPath: NSIndexPath): NSIndexPath {
@@ -1206,6 +1240,118 @@ class CollectionViewDataSource extends NSObject implements UICollectionViewDataS
12061240
return false;
12071241
}
12081242
}
1243+
// @NativeClass
1244+
// class UICollectionViewDragDelegateImpl extends NSObject implements UICollectionViewDragDelegate {
1245+
// public static ObjCProtocols = [UICollectionViewDragDelegate];
1246+
1247+
// _owner: WeakRef<CollectionView>;
1248+
// static initWithOwner(owner: CollectionView) {
1249+
// const delegate = UICollectionViewDragDelegateImpl.new() as UICollectionViewDragDelegateImpl;
1250+
// delegate._owner = new WeakRef(owner);
1251+
// return delegate;
1252+
// }
1253+
// // collectionViewDragPreviewParametersForItemAtIndexPath?(collectionView: UICollectionView, indexPath: NSIndexPath): UIDragPreviewParameters {
1254+
// // throw new Error('Method not implemented.');
1255+
// // }
1256+
// // collectionViewDragSessionAllowsMoveOperation?(collectionView: UICollectionView, session: UIDragSession): boolean {
1257+
// // console.log('collectionViewDragSessionAllowsMoveOperation', session, session.items.objectAtIndex(0))
1258+
// // return true;
1259+
// // }
1260+
// // collectionViewDragSessionDidEnd?(collectionView: UICollectionView, session: UIDragSession): void {
1261+
// // throw new Error('Method not implemented.');
1262+
// // }
1263+
// // collectionViewDragSessionIsRestrictedToDraggingApplication?(collectionView: UICollectionView, session: UIDragSession): boolean {
1264+
// // throw new Error('Method not implemented.');
1265+
// // }
1266+
// // collectionViewDragSessionWillBegin?(collectionView: UICollectionView, session: UIDragSession): void {
1267+
// // throw new Error('Method not implemented.');
1268+
// // }
1269+
// // collectionViewItemsForAddingToDragSessionAtIndexPathPoint?(collectionView: UICollectionView, session: UIDragSession, indexPath: NSIndexPath, point: CGPoint): NSArray<UIDragItem> {
1270+
// // throw new Error('Method not implemented.');
1271+
// // }
1272+
// collectionViewItemsForBeginningDragSessionAtIndexPath(collectionView: UICollectionView, session: UIDragSession, indexPath: NSIndexPath): NSArray<UIDragItem> {
1273+
// let owner = this._owner?.get();
1274+
// if (owner) {
1275+
// const result = owner.shouldMoveItemAtIndex(indexPath.row);
1276+
// console.log('collectionViewItemsForBeginningDragSessionAtIndexPath', indexPath.row, result)
1277+
// if (result) {
1278+
// let item = owner.getItemAtIndex(indexPath.row)
1279+
// let itemProvider = NSItemProvider.alloc().initWithObject(NSString.stringWithString(indexPath.row + ''))
1280+
// let dragItem = UIDragItem.alloc().initWithItemProvider(itemProvider)
1281+
// dragItem.localObject = item;
1282+
// return NSArray.arrayWithObject(dragItem);
1283+
// }
1284+
// }
1285+
// }
1286+
// }
1287+
1288+
// @NativeClass
1289+
// class UICollectionViewDropDelegateImpl extends NSObject implements UICollectionViewDropDelegate {
1290+
1291+
// public static ObjCProtocols = [UICollectionViewDropDelegate];
1292+
1293+
// _owner: WeakRef<CollectionView>;
1294+
// static initWithOwner(owner: CollectionView) {
1295+
// const delegate = UICollectionViewDropDelegateImpl.new() as UICollectionViewDropDelegateImpl;
1296+
// delegate._owner = new WeakRef(owner);
1297+
// return delegate;
1298+
// }
1299+
1300+
// // collectionViewCanHandleDropSession?(collectionView: UICollectionView, session: UIDropSession): boolean {
1301+
// // throw new Error('Method not implemented.');
1302+
// // }
1303+
// // collectionViewDropPreviewParametersForItemAtIndexPath?(collectionView: UICollectionView, indexPath: NSIndexPath): UIDragPreviewParameters {
1304+
// // throw new Error('Method not implemented.');
1305+
// // }
1306+
// // collectionViewDropSessionDidEnd?(collectionView: UICollectionView, session: UIDropSession): void {
1307+
// // throw new Error('Method not implemented.');
1308+
// // }
1309+
// // collectionViewDropSessionDidEnter?(collectionView: UICollectionView, session: UIDropSession): void {
1310+
// // throw new Error('Method not implemented.');
1311+
// // }
1312+
// // collectionViewDropSessionDidExit?(collectionView: UICollectionView, session: UIDropSession): void {
1313+
// // throw new Error('Method not implemented.');
1314+
// // }
1315+
// collectionViewDropSessionDidUpdateWithDestinationIndexPath?(collectionView: UICollectionView, session: UIDropSession, destinationIndexPath: NSIndexPath): UICollectionViewDropProposal {
1316+
// let owner = this._owner?.get();
1317+
// if (!owner || !destinationIndexPath) {
1318+
// return UICollectionViewDropProposal.alloc().initWithDropOperation(UIDropOperation.Forbidden);
1319+
// }
1320+
// const startPosition = (session.items.objectAtIndex(0).localObject as NSNumber).intValue;
1321+
// const endPosition = destinationIndexPath.row;
1322+
// if (owner) {
1323+
// if (!collectionView.hasActiveDrag || !owner._canReorderToPosition(startPosition, endPosition, endPosition)) {
1324+
// return UICollectionViewDropProposal.alloc().initWithDropOperation(UIDropOperation.Forbidden);
1325+
// }
1326+
// }
1327+
// owner._reorderItemInSource(startPosition, endPosition);
1328+
// return UICollectionViewDropProposal.alloc().initWithDropOperationIntent(UIDropOperation.Move, UICollectionViewDropIntent.InsertAtDestinationIndexPath);
1329+
// }
1330+
// collectionViewPerformDropWithCoordinator(collectionView: UICollectionView, coordinator: UICollectionViewDropCoordinator): void {
1331+
// let owner = this._owner?.get();
1332+
// if (owner) {
1333+
// const item =coordinator.items.objectAtIndex(0);
1334+
// if (item) {
1335+
1336+
// const destinationIndexPath = coordinator?.destinationIndexPath ?? {row:(collectionView.numberOfItemsInSection(0) -1), section:0} as NSIndexPath;
1337+
// console.log('dropItem', item, item.performSelector('sourceIndexPath'));
1338+
// const sourceIndexPath = item.performSelector('sourceIndexPath');
1339+
// console.log('collectionViewPerformDropWithCoordinator', destinationIndexPath, sourceIndexPath);
1340+
// // UIView.performWithoutAnimation(() => {
1341+
// collectionView.performBatchUpdatesCompletion(() => {
1342+
// owner._reorderItemInSource(sourceIndexPath.row, destinationIndexPath.row, false);
1343+
// owner._callItemReorderedEvent(sourceIndexPath.row, destinationIndexPath, owner.getItemAtIndex(sourceIndexPath.row));
1344+
// collectionView.deleteItemsAtIndexPaths(NSArray.arrayWithObject(sourceIndexPath));
1345+
// collectionView.insertItemsAtIndexPaths(NSArray.arrayWithObject(destinationIndexPath));
1346+
// }, null);
1347+
// // });
1348+
// coordinator.dropItemToItemAtIndexPath(item.performSelector('dragItem'), destinationIndexPath);
1349+
1350+
// }
1351+
1352+
// }
1353+
// }
1354+
// }
12091355
@NativeClass
12101356
class UICollectionViewDelegateImpl extends UICollectionViewCacheDelegateFlowLayout implements UICollectionViewDelegate {
12111357
_owner: WeakRef<CollectionView>;
@@ -1273,11 +1419,17 @@ class UICollectionViewDelegateImpl extends UICollectionViewCacheDelegateFlowLayo
12731419
owner.scrollViewDidEndScrollingAnimation(scrollView);
12741420
}
12751421
}
1276-
collectionViewTargetIndexPathForMoveFromItemAtIndexPathToProposedIndexPath(collectionView: UICollectionView, currentIndexPath: NSIndexPath, proposedIndexPath: NSIndexPath): NSIndexPath {
1422+
collectionViewTargetIndexPathForMoveFromItemAtIndexPathToProposedIndexPath(collectionView: UICollectionView, currentIndexPath: NSIndexPath, proposedIndexPath: NSIndexPath): NSIndexPath {
1423+
if (currentIndexPath === proposedIndexPath) {
1424+
return proposedIndexPath;
1425+
}
12771426
const owner = this._owner?.get();
12781427
if (owner && !owner._canReorderToPosition(currentIndexPath.row, proposedIndexPath.row, owner.getItemAtIndex(proposedIndexPath.row))) {
12791428
return currentIndexPath;
12801429
}
1430+
owner._reorderItemInSource(currentIndexPath.row, proposedIndexPath.row, false);
1431+
owner.clearCachedSize(currentIndexPath.row, proposedIndexPath.row);
1432+
12811433
return proposedIndexPath;
12821434
}
12831435
}

0 commit comments

Comments
 (0)