@nstudio/ui-collectionview 4.0.70 → 5.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ios.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ChangeType, ContentView, Observable, Property, ProxyViewContainer, Trace, Utils, View, paddingBottomProperty, paddingLeftProperty, paddingRightProperty, paddingTopProperty, profile } from '@nativescript/core';
2
- import { CLog, CLogTypes, CollectionViewBase, ListViewViewTypes, isBounceEnabledProperty, isScrollEnabledProperty, itemTemplatesProperty, orientationProperty, reorderLongPressEnabledProperty, reorderingEnabledProperty, reverseLayoutProperty, scrollBarIndicatorVisibleProperty } from './common';
2
+ import { reorderLongPressEnabledProperty, reorderingEnabledProperty, reverseLayoutProperty, scrollBarIndicatorVisibleProperty } from '.';
3
+ import { CLog, CLogTypes, CollectionViewBase, ListViewViewTypes, isBounceEnabledProperty, isScrollEnabledProperty, itemTemplatesProperty, orientationProperty } from './common';
3
4
  export * from './common';
4
5
  const infinity = Utils.layout.makeMeasureSpec(0, Utils.layout.UNSPECIFIED);
5
6
  export var ContentInsetAdjustmentBehavior;
@@ -43,11 +44,7 @@ export class CollectionView extends CollectionViewBase {
43
44
  this.needsScrollStartEvent = false;
44
45
  this.isScrolling = false;
45
46
  this._map = new Map();
46
- this._sizes = new Array();
47
- }
48
- // @ts-ignore
49
- get ios() {
50
- return this.nativeViewProtected;
47
+ // this._sizes = new Array<number[]>();
51
48
  }
52
49
  createNativeView() {
53
50
  let layout;
@@ -73,35 +70,27 @@ export class CollectionView extends CollectionViewBase {
73
70
  }
74
71
  onTemplateAdded(t) {
75
72
  super.onTemplateAdded(t);
76
- if (this.ios) {
77
- this.ios.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
73
+ if (this.nativeViewProtected) {
74
+ this.nativeViewProtected.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
78
75
  }
79
76
  }
80
77
  initNativeView() {
81
78
  super.initNativeView();
79
+ const nativeView = this.nativeView;
82
80
  this._dataSource = CollectionViewDataSource.initWithOwner(this);
83
- this.ios.dataSource = this._dataSource;
84
- const layoutStyle = CollectionViewBase.layoutStyles[this.layoutStyle];
85
- if (layoutStyle && layoutStyle.createDelegate) {
86
- this._delegate = layoutStyle.createDelegate();
87
- }
88
- else {
89
- this._delegate = UICollectionViewDelegateImpl.initWithOwner(this);
90
- }
91
- this._delegate._owner = new WeakRef(this);
81
+ nativeView.dataSource = this._dataSource;
82
+ // delegate will be set in first onLayout because we need computed _effectiveColWidth and _effectiveRowHeight
92
83
  this._measureCellMap = new Map();
93
- this.ios.delegate = this._delegate;
94
84
  this._setNativeClipToBounds();
95
85
  }
96
86
  disposeNativeView() {
97
87
  if (Trace.isEnabled()) {
98
88
  CLog(CLogTypes.log, 'disposeNativeView');
99
89
  }
100
- if (this.ios) {
101
- this.ios.delegate = null;
102
- this.ios.dataSource = null;
103
- }
90
+ const nativeView = this.nativeView;
91
+ nativeView.delegate = null;
104
92
  this._delegate = null;
93
+ nativeView.dataSource = null;
105
94
  this._dataSource = null;
106
95
  this._layout = null;
107
96
  this.reorderLongPressHandler = null;
@@ -132,14 +121,14 @@ export class CollectionView extends CollectionViewBase {
132
121
  }
133
122
  getViewForItemAtIndex(index) {
134
123
  let result;
135
- if (this.ios) {
136
- const cell = this.ios.cellForItemAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
124
+ if (this.nativeViewProtected) {
125
+ const cell = this.nativeViewProtected.cellForItemAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
137
126
  return cell?.view;
138
127
  }
139
128
  return result;
140
129
  }
141
130
  startDragging(index, pointer) {
142
- if (this.reorderEnabled && this.ios) {
131
+ if (this.reorderEnabled && this.nativeViewProtected) {
143
132
  this.manualDragging = true;
144
133
  this.draggingStartDelta = null;
145
134
  if (pointer) {
@@ -150,15 +139,16 @@ export class CollectionView extends CollectionViewBase {
150
139
  this.draggingStartDelta = [point.x - size.width / 2, point.y - size.height / 2];
151
140
  }
152
141
  }
153
- this.ios.beginInteractiveMovementForItemAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
142
+ this.nativeViewProtected.beginInteractiveMovementForItemAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
154
143
  this.scrollEnabledBeforeDragging = this.isScrollEnabled;
155
- this.ios.scrollEnabled = false;
144
+ this.nativeViewProtected.scrollEnabled = false;
156
145
  }
157
146
  }
158
147
  onReorderingTouch(event) {
159
148
  if (!this.manualDragging) {
160
149
  return;
161
150
  }
151
+ const collectionView = this.nativeViewProtected;
162
152
  const pointer = event.getActivePointers()[0];
163
153
  switch (event.action) {
164
154
  case 'move':
@@ -168,24 +158,18 @@ export class CollectionView extends CollectionViewBase {
168
158
  x -= this.draggingStartDelta[0];
169
159
  y -= this.draggingStartDelta[1];
170
160
  }
171
- if (this.ios) {
172
- this.ios.updateInteractiveMovementTargetPosition(CGPointMake(x, y));
173
- }
161
+ collectionView.updateInteractiveMovementTargetPosition(CGPointMake(x, y));
174
162
  break;
175
163
  case 'up':
176
164
  this.manualDragging = false;
177
- if (this.ios) {
178
- this.ios.endInteractiveMovement();
179
- this.ios.scrollEnabled = this.scrollEnabledBeforeDragging;
180
- }
165
+ collectionView && collectionView.endInteractiveMovement();
166
+ this.nativeViewProtected.scrollEnabled = this.scrollEnabledBeforeDragging;
181
167
  this.handleReorderEnd();
182
168
  break;
183
169
  case 'cancel':
184
170
  this.manualDragging = false;
185
- if (this.ios) {
186
- this.ios.cancelInteractiveMovement();
187
- this.ios.scrollEnabled = this.scrollEnabledBeforeDragging;
188
- }
171
+ collectionView && collectionView.cancelInteractiveMovement();
172
+ this.nativeViewProtected.scrollEnabled = this.scrollEnabledBeforeDragging;
189
173
  this.handleReorderEnd();
190
174
  break;
191
175
  }
@@ -203,31 +187,30 @@ export class CollectionView extends CollectionViewBase {
203
187
  this.reorderEndingRow = -1;
204
188
  }
205
189
  onReorderLongPress(gesture) {
206
- if (!this.ios) {
190
+ const collectionView = this.nativeViewProtected;
191
+ if (!collectionView) {
207
192
  return;
208
193
  }
209
194
  switch (gesture.state) {
210
195
  case 1 /* UIGestureRecognizerState.Began */:
211
- const selectedIndexPath = this.ios.indexPathForItemAtPoint(gesture.locationInView(this.ios));
212
- this.ios.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath);
196
+ const selectedIndexPath = collectionView.indexPathForItemAtPoint(gesture.locationInView(collectionView));
197
+ collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath);
213
198
  break;
214
199
  case 2 /* UIGestureRecognizerState.Changed */:
215
- this.ios.updateInteractiveMovementTargetPosition(gesture.locationInView(this.ios));
200
+ collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(collectionView));
216
201
  break;
217
202
  case 3 /* UIGestureRecognizerState.Ended */:
218
- this.ios.endInteractiveMovement();
203
+ collectionView.endInteractiveMovement();
219
204
  this.handleReorderEnd();
220
205
  break;
221
206
  default:
222
- this.ios.cancelInteractiveMovement();
207
+ collectionView.cancelInteractiveMovement();
223
208
  this.handleReorderEnd();
224
209
  break;
225
210
  }
226
211
  }
227
212
  [contentInsetAdjustmentBehaviorProperty.setNative](value) {
228
- if (this.ios) {
229
- this.ios.contentInsetAdjustmentBehavior = value;
230
- }
213
+ this.nativeViewProtected.contentInsetAdjustmentBehavior = value;
231
214
  }
232
215
  [paddingTopProperty.setNative](value) {
233
216
  this._setPadding({ top: Utils.layout.toDeviceIndependentPixels(this.effectivePaddingTop) });
@@ -254,33 +237,25 @@ export class CollectionView extends CollectionViewBase {
254
237
  this.updateScrollBarVisibility(this.scrollBarIndicatorVisible);
255
238
  }
256
239
  [isScrollEnabledProperty.setNative](value) {
257
- if (this.ios) {
258
- this.ios.scrollEnabled = value;
259
- }
240
+ this.nativeViewProtected.scrollEnabled = value;
260
241
  this.scrollEnabledBeforeDragging = value;
261
242
  }
262
243
  [isBounceEnabledProperty.setNative](value) {
263
- if (this.ios) {
264
- this.ios.bounces = value;
265
- // this.ios.alwaysBounceHorizontal = value;
266
- }
244
+ this.nativeViewProtected.bounces = value;
245
+ // this.nativeViewProtected.alwaysBounceHorizontal = value;
267
246
  }
268
247
  [itemTemplatesProperty.getDefault]() {
269
248
  return null;
270
249
  }
271
250
  [reverseLayoutProperty.setNative](value) {
272
- if (this.ios) {
273
- this.ios.transform = value ? CGAffineTransformMakeRotation(-Math.PI) : null;
274
- }
251
+ this.nativeViewProtected.transform = value ? CGAffineTransformMakeRotation(-Math.PI) : null;
275
252
  }
276
253
  [reorderLongPressEnabledProperty.setNative](value) {
277
254
  if (value) {
278
255
  if (!this.reorderLongPressGesture) {
279
256
  this.reorderLongPressHandler = ReorderLongPressImpl.initWithOwner(new WeakRef(this));
280
257
  this.reorderLongPressGesture = UILongPressGestureRecognizer.alloc().initWithTargetAction(this.reorderLongPressHandler, 'longPress');
281
- if (this.ios) {
282
- this.ios.addGestureRecognizer(this.reorderLongPressGesture);
283
- }
258
+ this.nativeViewProtected.addGestureRecognizer(this.reorderLongPressGesture);
284
259
  }
285
260
  else {
286
261
  this.reorderLongPressGesture.enabled = true;
@@ -307,14 +282,14 @@ export class CollectionView extends CollectionViewBase {
307
282
  this.updateScrollBarVisibility(value);
308
283
  }
309
284
  updateScrollBarVisibility(value) {
310
- if (!this.ios) {
285
+ if (!this.nativeViewProtected) {
311
286
  return;
312
287
  }
313
288
  if (this.orientation === 'horizontal') {
314
- this.ios.showsHorizontalScrollIndicator = value;
289
+ this.nativeViewProtected.showsHorizontalScrollIndicator = value;
315
290
  }
316
291
  else {
317
- this.ios.showsVerticalScrollIndicator = value;
292
+ this.nativeViewProtected.showsVerticalScrollIndicator = value;
318
293
  }
319
294
  }
320
295
  eachChildView(callback) {
@@ -332,13 +307,36 @@ export class CollectionView extends CollectionViewBase {
332
307
  const p = CollectionViewBase.plugins[k];
333
308
  p.onLayout && p.onLayout(this, left, top, right, bottom);
334
309
  });
335
- const layoutView = this.ios?.collectionViewLayout;
310
+ const layoutView = this.nativeViewProtected.collectionViewLayout;
336
311
  if (!layoutView) {
337
312
  return;
338
313
  }
339
- if ((layoutView instanceof UICollectionViewFlowLayout && this._effectiveColWidth) || this._effectiveRowHeight) {
340
- // @ts-ignore
341
- layoutView.estimatedItemSize = layoutView.itemSize = CGSizeMake(Utils.layout.toDeviceIndependentPixels(this._effectiveColWidth), Utils.layout.toDeviceIndependentPixels(this._effectiveRowHeight));
314
+ if (!this._delegate) {
315
+ const layoutStyle = CollectionViewBase.layoutStyles[this.layoutStyle];
316
+ if (layoutStyle && layoutStyle.createDelegate) {
317
+ this._delegate = layoutStyle.createDelegate(this);
318
+ }
319
+ else {
320
+ // if we use fixed col and row size we want a delegate
321
+ // without collectionViewLayoutSizeForItemAtIndexPath
322
+ // because it is not needed and faster
323
+ if (this._effectiveColWidth && this._effectiveRowHeight) {
324
+ this._delegate = UICollectionViewDelegateFixedSizeImpl.initWithOwner(this);
325
+ }
326
+ else {
327
+ this._delegate = UICollectionViewDelegateImpl.initWithOwner(this);
328
+ }
329
+ }
330
+ // this._delegate._owner = new WeakRef(this);
331
+ this.nativeViewProtected.delegate = this._delegate;
332
+ }
333
+ if (layoutView instanceof UICollectionViewFlowLayout) {
334
+ if (this._effectiveRowHeight && this._effectiveColWidth) {
335
+ layoutView.itemSize = CGSizeMake(Utils.layout.toDeviceIndependentPixels(this._effectiveColWidth), Utils.layout.toDeviceIndependentPixels(this._effectiveRowHeight));
336
+ }
337
+ else {
338
+ layoutView.estimatedItemSize = CGSizeMake(Utils.layout.toDeviceIndependentPixels(this._effectiveColWidth), Utils.layout.toDeviceIndependentPixels(this._effectiveRowHeight));
339
+ }
342
340
  }
343
341
  layoutView.invalidateLayout();
344
342
  // there is no need to call refresh if it was triggered before with same size.
@@ -352,99 +350,111 @@ export class CollectionView extends CollectionViewBase {
352
350
  return this.orientation === 'horizontal';
353
351
  }
354
352
  onSourceCollectionChanged(event) {
355
- if (!this.ios || this._dataUpdatesSuspended) {
353
+ const view = this.nativeViewProtected;
354
+ if (!view || this._dataUpdatesSuspended || !this._lastLayoutKey) {
356
355
  return;
357
356
  }
358
357
  if (Trace.isEnabled()) {
359
358
  CLog(CLogTypes.log, 'onItemsChanged', ChangeType.Update, event.action, event.index, event.addedCount, event.removed && event.removed.length);
360
359
  }
361
360
  // we need to clear stored cell sizes and it wont be correct anymore
362
- this.clearCellSize();
361
+ // this.clearCellSize();
362
+ const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
363
363
  switch (event.action) {
364
364
  case ChangeType.Delete: {
365
365
  const indexes = NSMutableArray.new();
366
366
  for (let index = 0; index < event.addedCount; index++) {
367
367
  indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
368
+ if (sizes) {
369
+ sizes.removeObjectAtIndex(event.index);
370
+ }
368
371
  }
372
+ // this._sizes.splice(event.index, event.addedCount);
369
373
  this.unbindUnusedCells(event.removed);
370
374
  if (Trace.isEnabled()) {
371
375
  CLog(CLogTypes.info, 'deleteItemsAtIndexPaths', indexes.count);
372
376
  }
373
- this.ios.performBatchUpdatesCompletion(() => {
374
- if (this.ios) {
375
- this.ios.deleteItemsAtIndexPaths(indexes);
376
- }
377
+ view.performBatchUpdatesCompletion(() => {
378
+ view.deleteItemsAtIndexPaths(indexes);
377
379
  }, null);
378
380
  return;
379
381
  }
380
382
  case ChangeType.Update: {
381
383
  const indexes = NSMutableArray.new();
382
384
  indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index, 0));
385
+ if (sizes) {
386
+ sizes.replaceObjectAtIndexWithObject(event.index, NSValue.valueWithCGSize(CGSizeZero));
387
+ }
388
+ // this._sizes[event.index] = null;
383
389
  if (Trace.isEnabled()) {
384
390
  CLog(CLogTypes.info, 'reloadItemsAtIndexPaths', event.index, indexes.count);
385
391
  }
386
- UIView.performWithoutAnimation(() => {
387
- this.ios.performBatchUpdatesCompletion(() => {
388
- if (this.ios) {
389
- this.ios.reloadItemsAtIndexPaths(indexes);
390
- }
391
- }, null);
392
- });
392
+ view.performBatchUpdatesCompletion(() => {
393
+ view.reloadItemsAtIndexPaths(indexes);
394
+ }, null);
393
395
  return;
394
396
  }
395
397
  case ChangeType.Add: {
396
398
  const indexes = NSMutableArray.new();
397
399
  for (let index = 0; index < event.addedCount; index++) {
398
400
  indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
401
+ if (sizes) {
402
+ sizes.insertObjectAtIndex(NSValue.valueWithCGSize(CGSizeZero), event.index);
403
+ }
404
+ // this._sizes.splice(index, 0, null);
399
405
  }
400
406
  if (Trace.isEnabled()) {
401
407
  CLog(CLogTypes.info, 'insertItemsAtIndexPaths', indexes.count);
402
408
  }
403
- this.ios.performBatchUpdatesCompletion(() => {
404
- if (this.ios) {
405
- this.ios.insertItemsAtIndexPaths(indexes);
406
- }
409
+ view.performBatchUpdatesCompletion(() => {
410
+ view.insertItemsAtIndexPaths(indexes);
407
411
  }, null);
408
412
  return;
409
413
  }
410
414
  case ChangeType.Splice: {
411
- this.ios.performBatchUpdatesCompletion(() => {
412
- if (!this.ios) {
413
- return;
414
- }
415
+ view.performBatchUpdatesCompletion(() => {
415
416
  const added = event.addedCount;
416
417
  const removed = (event.removed && event.removed.length) || 0;
417
418
  if (added > 0 && added === removed) {
418
419
  const indexes = NSMutableArray.new();
419
420
  for (let index = 0; index < added; index++) {
420
421
  indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
422
+ if (sizes) {
423
+ sizes.replaceObjectAtIndexWithObject(event.index + index, NSValue.valueWithCGSize(CGSizeZero));
424
+ }
425
+ // this._sizes[event.index + index] = null;
421
426
  }
422
- this.ios.reloadItemsAtIndexPaths(indexes);
427
+ view.reloadItemsAtIndexPaths(indexes);
423
428
  }
424
429
  else {
425
430
  if (event.addedCount > 0) {
426
431
  const indexes = NSMutableArray.alloc().init();
427
432
  for (let index = 0; index < event.addedCount; index++) {
428
433
  indexes.addObject(NSIndexPath.indexPathForItemInSection(event.index + index, 0));
434
+ if (sizes) {
435
+ sizes.insertObjectAtIndex(NSValue.valueWithCGSize(CGSizeZero), event.index);
436
+ }
437
+ // this._sizes.splice(event.index, 0, null);
429
438
  }
430
- this.ios.insertItemsAtIndexPaths(indexes);
439
+ view.insertItemsAtIndexPaths(indexes);
431
440
  }
432
441
  if (event.removed && event.removed.length > 0) {
433
442
  const indexes = NSMutableArray.new();
434
443
  for (let index = 0; index < event.removed.length; index++) {
435
444
  indexes.addObject(NSIndexPath.indexPathForItemInSection(event.index + index, 0));
445
+ if (sizes) {
446
+ sizes.removeObjectAtIndex(event.index);
447
+ }
436
448
  }
449
+ // this._sizes.splice(event.index, event.removed.length);
437
450
  this.unbindUnusedCells(event.removed);
438
451
  if (Trace.isEnabled()) {
439
452
  CLog(CLogTypes.info, 'deleteItemsAtIndexPaths', indexes.count);
440
453
  }
441
- this.ios.performBatchUpdatesCompletion(() => {
442
- if (this.ios) {
443
- this.ios.deleteItemsAtIndexPaths(indexes);
444
- }
445
- }, null);
454
+ view.deleteItemsAtIndexPaths(indexes);
446
455
  }
447
456
  }
457
+ // view.collectionViewLayout.invalidateLayout();
448
458
  }, null);
449
459
  return;
450
460
  }
@@ -453,13 +463,12 @@ export class CollectionView extends CollectionViewBase {
453
463
  }
454
464
  onItemTemplatesChanged(oldValue, newValue) {
455
465
  super.onItemTemplatesChanged(oldValue, newValue);
456
- if (!this.ios) {
466
+ if (!this.nativeViewProtected) {
457
467
  return;
458
468
  }
469
+ const view = this.nativeViewProtected;
459
470
  this._itemTemplatesInternal.forEach((t) => {
460
- if (this.ios) {
461
- this.ios.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
462
- }
471
+ view.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
463
472
  });
464
473
  }
465
474
  unbindUnusedCells(removedDataItems) {
@@ -473,27 +482,34 @@ export class CollectionView extends CollectionViewBase {
473
482
  }, this);
474
483
  }
475
484
  refreshVisibleItems() {
476
- if (!this.ios) {
485
+ const view = this.nativeViewProtected;
486
+ if (!view) {
477
487
  return;
478
488
  }
479
- const visibles = this.ios.indexPathsForVisibleItems;
489
+ const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
490
+ const visibles = view.indexPathsForVisibleItems;
491
+ if (sizes?.count) {
492
+ const indexes = Array.from(visibles);
493
+ indexes.forEach((value) => {
494
+ sizes.replaceObjectAtIndexWithObject(value.row, NSValue.valueWithCGSize(CGSizeZero));
495
+ });
496
+ }
480
497
  UIView.performWithoutAnimation(() => {
481
- this.ios.performBatchUpdatesCompletion(() => {
482
- if (this.ios) {
483
- this.ios.reloadItemsAtIndexPaths(visibles);
484
- }
498
+ view.performBatchUpdatesCompletion(() => {
499
+ view.reloadItemsAtIndexPaths(visibles);
485
500
  }, null);
486
501
  });
487
502
  }
488
503
  isItemAtIndexVisible(itemIndex) {
489
- if (!this.ios) {
504
+ const view = this.nativeViewProtected;
505
+ if (!view) {
490
506
  return false;
491
507
  }
492
- const indexes = Array.from(this.ios.indexPathsForVisibleItems);
508
+ const indexes = Array.from(view.indexPathsForVisibleItems);
493
509
  return indexes.some((visIndex) => visIndex.row === itemIndex);
494
510
  }
495
511
  refresh() {
496
- if (!this.isLoaded || !this.ios) {
512
+ if (!this.isLoaded || !this.nativeView) {
497
513
  this._isDataDirty = true;
498
514
  return;
499
515
  }
@@ -503,7 +519,11 @@ export class CollectionView extends CollectionViewBase {
503
519
  CLog(CLogTypes.info, 'refresh');
504
520
  }
505
521
  // we need to clear stored cell sizes and it wont be correct anymore
506
- this.clearCellSize();
522
+ // this.clearCellSize();
523
+ const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
524
+ if (sizes) {
525
+ sizes.removeAllObjects();
526
+ }
507
527
  // clear bindingContext when it is not observable because otherwise bindings to items won't reevaluate
508
528
  this._map.forEach((view, nativeView, map) => {
509
529
  if (!(view.bindingContext instanceof Observable)) {
@@ -513,7 +533,7 @@ export class CollectionView extends CollectionViewBase {
513
533
  // TODO: this is ugly look here: https://github.com/nativescript-vue/nativescript-vue/issues/525
514
534
  // this.clearRealizedCells();
515
535
  // dispatch_async(main_queue, () => {
516
- this.ios.reloadData();
536
+ this.nativeViewProtected.reloadData();
517
537
  // });
518
538
  const args = {
519
539
  eventName: CollectionViewBase.dataPopulatedEvent,
@@ -523,18 +543,17 @@ export class CollectionView extends CollectionViewBase {
523
543
  }
524
544
  //@ts-ignore
525
545
  get scrollOffset() {
526
- return (this.isHorizontal() ? this.ios?.contentOffset.x : this.ios?.contentOffset.y) || 0;
546
+ const view = this.nativeViewProtected;
547
+ return (this.isHorizontal() ? view?.contentOffset.x : view?.contentOffset.y) || 0;
527
548
  }
528
549
  get verticalOffsetX() {
529
- return this.ios?.contentOffset.x || 0;
550
+ return this.nativeViewProtected?.contentOffset.x || 0;
530
551
  }
531
552
  get verticalOffsetY() {
532
- return this.ios?.contentOffset.y || 0;
553
+ return this.nativeViewProtected?.contentOffset.y || 0;
533
554
  }
534
555
  scrollToIndex(index, animated = true) {
535
- if (this.ios) {
536
- this.ios.scrollToItemAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), this.orientation === 'vertical' ? 1 /* UICollectionViewScrollPosition.Top */ : 8 /* UICollectionViewScrollPosition.Left */, animated);
537
- }
556
+ this.nativeViewProtected.scrollToItemAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0), this.orientation === 'vertical' ? 1 /* UICollectionViewScrollPosition.Top */ : 8 /* UICollectionViewScrollPosition.Left */, animated);
538
557
  }
539
558
  requestLayout() {
540
559
  // When preparing cell don't call super - no need to invalidate our measure when cell desiredSize is changed.
@@ -543,9 +562,7 @@ export class CollectionView extends CollectionViewBase {
543
562
  }
544
563
  }
545
564
  _setNativeClipToBounds() {
546
- if (this.ios) {
547
- this.ios.clipsToBounds = true;
548
- }
565
+ this.nativeView.clipsToBounds = true;
549
566
  }
550
567
  notifyForItemAtIndex(listView, cell, view, eventName, indexPath, bindingContext) {
551
568
  const args = { eventName, object: listView, index: indexPath.row, view, ios: cell, bindingContext };
@@ -556,7 +573,7 @@ export class CollectionView extends CollectionViewBase {
556
573
  const selector = this._itemTemplateSelector;
557
574
  let type = this._defaultTemplate.key;
558
575
  if (selector) {
559
- type = selector(this.getItemAtIndex(indexPath.item), indexPath.item, this.items);
576
+ type = selector.call(this, this.getItemAtIndex(indexPath.item), indexPath.item, this.items);
560
577
  }
561
578
  return type.toLowerCase();
562
579
  }
@@ -578,6 +595,7 @@ export class CollectionView extends CollectionViewBase {
578
595
  }
579
596
  const args = this.notifyForItemAtIndex(this, cell, view, CollectionViewBase.itemLoadingEvent, indexPath, bindingContext);
580
597
  view = args.view;
598
+ view.bindingContext = bindingContext;
581
599
  if (view instanceof ProxyViewContainer) {
582
600
  const sp = new ContentView();
583
601
  sp.content = view;
@@ -591,30 +609,38 @@ export class CollectionView extends CollectionViewBase {
591
609
  cell.view.nativeViewProtected.removeFromSuperview();
592
610
  cell.owner = new WeakRef(view);
593
611
  }
612
+ cell.currentIndex = indexPath.row;
594
613
  if (notForCellSizeComp) {
595
614
  this._map.set(cell, view);
596
615
  }
597
616
  if (view && !view.parent) {
598
617
  this._addView(view);
599
618
  const innerView = NSCellView.new();
619
+ innerView.autoresizingMask = 2 /* UIViewAutoresizing.FlexibleWidth */ | 16 /* UIViewAutoresizing.FlexibleHeight */;
600
620
  innerView.view = new WeakRef(view);
601
- if (!notForCellSizeComp || this.autoReloadItemOnLayout) {
621
+ if (notForCellSizeComp && this.autoReloadItemOnLayout) {
602
622
  // for a cell to update correctly on cell layout change we need
603
623
  // to do it ourself instead of "propagating it"
604
624
  view['performLayout'] = () => {
605
- if (notForCellSizeComp) {
606
- this.measureCell(cell, view, indexPath);
607
- this.layoutCell(indexPath.row, cell, view);
608
- if (this.ios) {
609
- this.ios.collectionViewLayout.invalidateLayout();
625
+ if (!this._preparingCell) {
626
+ const index = cell.currentIndex;
627
+ const nativeView = this.nativeViewProtected;
628
+ const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
629
+ if (sizes) {
630
+ sizes.replaceObjectAtIndexWithObject(index, NSValue.valueWithCGSize(CGSizeZero));
610
631
  }
632
+ nativeView.performBatchUpdatesCompletion(() => {
633
+ this.measureCell(cell, view, index);
634
+ this.notifyForItemAtIndex(this, cell, view, CollectionViewBase.itemLoadingEvent, indexPath, view.bindingContext);
635
+ }, null);
636
+ nativeView.collectionViewLayout.invalidateLayout();
611
637
  }
612
638
  };
613
639
  }
614
640
  innerView.addSubview(view.nativeViewProtected);
615
641
  cell.contentView.addSubview(innerView);
616
642
  }
617
- cellSize = this.measureCell(cell, view, indexPath);
643
+ cellSize = this.measureCell(cell, view, indexPath.row);
618
644
  if (notForCellSizeComp) {
619
645
  view.notify({ eventName: CollectionViewBase.bindedEvent });
620
646
  }
@@ -628,7 +654,8 @@ export class CollectionView extends CollectionViewBase {
628
654
  return cellSize;
629
655
  }
630
656
  getCellSize(index) {
631
- let result = this._sizes[index];
657
+ // let result = this._sizes[index];
658
+ let result;
632
659
  // CLog(CLogTypes.log, 'getCellSize', index, result, this._effectiveColWidth, this._effectiveRowHeight, this.getMeasuredWidth(), this.getMeasuredHeight());
633
660
  if (!result) {
634
661
  let width = this._effectiveColWidth;
@@ -657,19 +684,18 @@ export class CollectionView extends CollectionViewBase {
657
684
  // return undefined;
658
685
  return result;
659
686
  }
660
- storeCellSize(index, value) {
661
- this._sizes[index] = value;
662
- }
663
- clearCellSize() {
664
- this._sizes = new Array();
665
- }
666
- measureCell(cell, cellView, index) {
687
+ // public storeCellSize(index: number, value) {
688
+ // this._sizes[index] = value;
689
+ // }
690
+ // public clearCellSize() {
691
+ // this._sizes = new Array<number[]>();
692
+ // }
693
+ measureCell(cell, cellView, position) {
667
694
  if (cellView) {
668
695
  let width = this._effectiveColWidth;
669
696
  let height = this._effectiveRowHeight;
670
697
  const horizontal = this.isHorizontal();
671
698
  if (this.spanSize) {
672
- const position = index.row;
673
699
  const dataItem = this.getItemAtIndex(position);
674
700
  const spanSize = this.spanSize(dataItem, position);
675
701
  if (horizontal) {
@@ -690,19 +716,20 @@ export class CollectionView extends CollectionViewBase {
690
716
  ? Utils.layout.makeMeasureSpec(this._innerHeight, Utils.layout.UNSPECIFIED)
691
717
  : infinity;
692
718
  if (Trace.isEnabled()) {
693
- CLog(CLogTypes.log, 'measureCell', index.row, width, height, widthMeasureSpec, heightMeasureSpec);
719
+ CLog(CLogTypes.log, 'measureCell', position, width, height, widthMeasureSpec, heightMeasureSpec);
694
720
  }
695
721
  const measuredSize = View.measureChild(this, cellView, widthMeasureSpec, heightMeasureSpec);
696
722
  const result = [measuredSize.measuredWidth, measuredSize.measuredHeight];
697
- this.storeCellSize(index.row, result);
723
+ // this.storeCellSize(index.row, result);
698
724
  return result;
699
725
  }
700
726
  return undefined;
701
727
  }
702
728
  layoutCell(index, cell, cellView) {
703
- const cellSize = this.getCellSize(index);
729
+ // const cellSize = this.getCellSize(index);
704
730
  cellView['iosIgnoreSafeArea'] = true;
705
- View.layoutChild(this, cellView, 0, 0, cellSize[0], cellSize[1]);
731
+ const size = cell.bounds.size;
732
+ View.layoutChild(this, cellView, 0, 0, Utils.layout.toDevicePixels(size.width), Utils.layout.toDevicePixels(size.height));
706
733
  if (Trace.isEnabled()) {
707
734
  CLog(CLogTypes.log, 'layoutCell', index, cellView.getMeasuredWidth(), cellView.getMeasuredHeight());
708
735
  }
@@ -759,6 +786,7 @@ export class CollectionView extends CollectionViewBase {
759
786
  collectionViewCellForItemAtIndexPath(collectionView, indexPath) {
760
787
  const templateType = this._getItemTemplateType(indexPath);
761
788
  let cell = collectionView.dequeueReusableCellWithReuseIdentifierForIndexPath(templateType, indexPath);
789
+ const firstRender = !cell.view;
762
790
  if (!cell) {
763
791
  cell = CollectionViewCell.new();
764
792
  }
@@ -766,8 +794,9 @@ export class CollectionView extends CollectionViewBase {
766
794
  CLog(CLogTypes.log, 'collectionViewCellForItemAtIndexPath', indexPath.row, templateType, !!cell.view, cell);
767
795
  }
768
796
  this._prepareCell(cell, indexPath, templateType);
797
+ // the cell layout will be called from NSCellView layoutSubviews
769
798
  const cellView = cell.view;
770
- if (cellView['isLayoutRequired']) {
799
+ if (!firstRender && cellView['isLayoutRequired']) {
771
800
  this.layoutCell(indexPath.row, cell, cellView);
772
801
  }
773
802
  return cell;
@@ -785,14 +814,13 @@ export class CollectionView extends CollectionViewBase {
785
814
  });
786
815
  }
787
816
  }
788
- if (this.hasListeners(CollectionViewBase.displayItemEvent)) {
789
- this.notify({
790
- eventName: CollectionViewBase.displayItemEvent,
791
- index: indexPath.row,
792
- object: this,
793
- cell,
794
- });
795
- }
817
+ // if (this.hasListeners(CollectionViewBase.displayItemEvent) ) {
818
+ // this.notify<CollectionViewItemDisplayEventData>({
819
+ // eventName: CollectionViewBase.displayItemEvent,
820
+ // index:indexPath.row,
821
+ // object: this,
822
+ // });
823
+ // }
796
824
  if (cell.preservesSuperviewLayoutMargins) {
797
825
  cell.preservesSuperviewLayoutMargins = false;
798
826
  }
@@ -956,6 +984,15 @@ var CollectionViewCell = /** @class */ (function (_super) {
956
984
  enumerable: true,
957
985
  configurable: true
958
986
  });
987
+ CollectionViewCell.prototype.systemLayoutSizeFittingSizeWithHorizontalFittingPriorityVerticalFittingPriority = function (targetSize, horizontalFittingPriority, verticalFittingPriority) {
988
+ var _a;
989
+ var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.deref();
990
+ if (owner) {
991
+ var dimensions = { measuredWidth: owner.getMeasuredWidth(), measuredHeight: owner.getMeasuredHeight() };
992
+ return CGSizeMake(Utils.layout.toDeviceIndependentPixels(dimensions.measuredWidth), Utils.layout.toDeviceIndependentPixels(dimensions.measuredHeight));
993
+ }
994
+ return targetSize;
995
+ };
959
996
  return CollectionViewCell;
960
997
  }(UICollectionViewCell));
961
998
  var CollectionViewDataSource = /** @class */ (function (_super) {
@@ -1041,19 +1078,14 @@ var UICollectionViewDelegateImpl = /** @class */ (function (_super) {
1041
1078
  }
1042
1079
  return indexPath;
1043
1080
  };
1044
- UICollectionViewDelegateImpl.prototype.collectionViewDidHighlightItemAtIndexPath = function (collectionView, indexPath) {
1045
- var owner = this._owner.deref();
1046
- if (owner) {
1047
- return owner.collectionViewDidHighlightItemAtIndexPath(collectionView, indexPath);
1048
- }
1049
- };
1050
- UICollectionViewDelegateImpl.prototype.collectionViewDidUnhighlightItemAtIndexPath = function (collectionView, indexPath) {
1081
+ UICollectionViewDelegateImpl.prototype.collectionViewLayoutSizeForItemAtIndexPath = function (collectionView, collectionViewLayout, indexPath) {
1051
1082
  var owner = this._owner.deref();
1052
1083
  if (owner) {
1053
- return owner.collectionViewDidUnhighlightItemAtIndexPath(collectionView, indexPath);
1084
+ return owner.collectionViewLayoutSizeForItemAtIndexPath(collectionView, collectionViewLayout, indexPath);
1054
1085
  }
1086
+ return CGSizeZero;
1055
1087
  };
1056
- UICollectionViewDelegateImpl.prototype.collectionViewLayoutSizeForItemAtIndexPath = function (collectionView, collectionViewLayout, indexPath) {
1088
+ UICollectionViewDelegateImpl.prototype.collectionViewLayoutComputedSizeForItemAtIndexPath = function (collectionView, collectionViewLayout, indexPath) {
1057
1089
  var owner = this._owner.deref();
1058
1090
  if (owner) {
1059
1091
  return owner.collectionViewLayoutSizeForItemAtIndexPath(collectionView, collectionViewLayout, indexPath);
@@ -1098,6 +1130,68 @@ var UICollectionViewDelegateImpl = /** @class */ (function (_super) {
1098
1130
  };
1099
1131
  UICollectionViewDelegateImpl.ObjCProtocols = [UICollectionViewDelegate, UICollectionViewDelegateFlowLayout];
1100
1132
  return UICollectionViewDelegateImpl;
1133
+ }(UICollectionViewCacheDelegateFlowLayout));
1134
+ var UICollectionViewDelegateFixedSizeImpl = /** @class */ (function (_super) {
1135
+ __extends(UICollectionViewDelegateFixedSizeImpl, _super);
1136
+ function UICollectionViewDelegateFixedSizeImpl() {
1137
+ return _super !== null && _super.apply(this, arguments) || this;
1138
+ }
1139
+ UICollectionViewDelegateFixedSizeImpl.initWithOwner = function (owner) {
1140
+ var delegate = UICollectionViewDelegateFixedSizeImpl.new();
1141
+ delegate._owner = new WeakRef(owner);
1142
+ return delegate;
1143
+ };
1144
+ UICollectionViewDelegateFixedSizeImpl.prototype.collectionViewWillDisplayCellForItemAtIndexPath = function (collectionView, cell, indexPath) {
1145
+ var owner = this._owner.deref();
1146
+ if (owner) {
1147
+ owner.collectionViewWillDisplayCellForItemAtIndexPath(collectionView, cell, indexPath);
1148
+ }
1149
+ };
1150
+ UICollectionViewDelegateFixedSizeImpl.prototype.collectionViewDidSelectItemAtIndexPath = function (collectionView, indexPath) {
1151
+ var owner = this._owner.deref();
1152
+ if (owner) {
1153
+ return owner.collectionViewDidSelectItemAtIndexPath(collectionView, indexPath);
1154
+ }
1155
+ return indexPath;
1156
+ };
1157
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewDidScroll = function (scrollView) {
1158
+ var owner = this._owner.deref();
1159
+ if (owner) {
1160
+ owner.scrollViewDidScroll(scrollView);
1161
+ }
1162
+ };
1163
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewWillBeginDragging = function (scrollView) {
1164
+ var owner = this._owner.deref();
1165
+ if (owner) {
1166
+ owner.scrollViewWillBeginDragging(scrollView);
1167
+ }
1168
+ };
1169
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewDidEndDecelerating = function (scrollView) {
1170
+ var owner = this._owner.deref();
1171
+ if (owner) {
1172
+ owner.scrollViewDidEndDecelerating(scrollView);
1173
+ }
1174
+ };
1175
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewWillEndDraggingWithVelocityTargetContentOffset = function (scrollView, velocity, targetContentOffset) {
1176
+ var owner = this._owner.deref();
1177
+ if (owner) {
1178
+ owner.scrollViewWillEndDraggingWithVelocityTargetContentOffset(scrollView, velocity, targetContentOffset);
1179
+ }
1180
+ };
1181
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewDidEndDraggingWillDecelerate = function (scrollView, decelerate) {
1182
+ var owner = this._owner.deref();
1183
+ if (owner) {
1184
+ owner.scrollViewDidEndDraggingWillDecelerate(scrollView, decelerate);
1185
+ }
1186
+ };
1187
+ UICollectionViewDelegateFixedSizeImpl.prototype.scrollViewDidEndScrollingAnimation = function (scrollView) {
1188
+ var owner = this._owner.deref();
1189
+ if (owner) {
1190
+ owner.scrollViewDidEndScrollingAnimation(scrollView);
1191
+ }
1192
+ };
1193
+ UICollectionViewDelegateFixedSizeImpl.ObjCProtocols = [UICollectionViewDelegate, UICollectionViewDelegateFlowLayout];
1194
+ return UICollectionViewDelegateFixedSizeImpl;
1101
1195
  }(NSObject));
1102
1196
  var ReorderLongPressImpl = /** @class */ (function (_super) {
1103
1197
  __extends(ReorderLongPressImpl, _super);