@nstudio/ui-collectionview 5.1.7 → 5.1.9-alpha.0

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,6 +1,5 @@
1
1
  import { ChangeType, ContentView, Observable, Property, ProxyViewContainer, Trace, Utils, View, paddingBottomProperty, paddingLeftProperty, paddingRightProperty, paddingTopProperty, profile } from '@nativescript/core';
2
- import { reorderLongPressEnabledProperty, reorderingEnabledProperty, reverseLayoutProperty, scrollBarIndicatorVisibleProperty } from '.';
3
- import { CLog, CLogTypes, CollectionViewBase, ListViewViewTypes, isBounceEnabledProperty, isScrollEnabledProperty, itemTemplatesProperty, orientationProperty } from './common';
2
+ import { CLog, CLogTypes, CollectionViewBase, ViewTemplateType, isBounceEnabledProperty, isScrollEnabledProperty, itemTemplatesProperty, orientationProperty, reorderLongPressEnabledProperty, reorderingEnabledProperty, reverseLayoutProperty, scrollBarIndicatorVisibleProperty, getUUID } from './common';
4
3
  export * from './common';
5
4
  const infinity = Utils.layout.makeMeasureSpec(0, Utils.layout.UNSPECIFIED);
6
5
  export var ContentInsetAdjustmentBehavior;
@@ -44,7 +43,6 @@ export class CollectionView extends CollectionViewBase {
44
43
  this.needsScrollStartEvent = false;
45
44
  this.isScrolling = false;
46
45
  this._map = new Map();
47
- // this._sizes = new Array<number[]>();
48
46
  }
49
47
  createNativeView() {
50
48
  let layout;
@@ -60,25 +58,20 @@ export class CollectionView extends CollectionViewBase {
60
58
  }
61
59
  const view = UICollectionView.alloc().initWithFrameCollectionViewLayout(CGRectMake(0, 0, 0, 0), layout);
62
60
  view.backgroundColor = UIColor.clearColor;
63
- this._itemTemplatesInternal.forEach((t) => {
64
- view.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
65
- });
66
61
  view.autoresizesSubviews = false;
67
62
  view.autoresizingMask = 0 /* UIViewAutoresizing.None */;
68
63
  this.lastContentOffset = view.contentOffset;
69
64
  return view;
70
65
  }
71
- onTemplateAdded(t) {
72
- super.onTemplateAdded(t);
73
- if (this.nativeViewProtected) {
74
- this.nativeViewProtected.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
75
- }
76
- }
66
+ // onTemplateAdded(t) {
67
+ // super.onTemplateAdded(t);
68
+ // if (this.nativeViewProtected) {
69
+ // // this.nativeViewProtected.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
70
+ // }
71
+ // }
77
72
  initNativeView() {
78
73
  super.initNativeView();
79
- const nativeView = this.nativeView;
80
- this._dataSource = CollectionViewDataSource.initWithOwner(this);
81
- nativeView.dataSource = this._dataSource;
74
+ this.setupDataSource();
82
75
  // delegate will be set in first onLayout because we need computed _effectiveColWidth and _effectiveRowHeight
83
76
  this._measureCellMap = new Map();
84
77
  // waterfall requires the delegate to be set as soon as possible
@@ -91,6 +84,119 @@ export class CollectionView extends CollectionViewBase {
91
84
  }
92
85
  this._setNativeClipToBounds();
93
86
  }
87
+ setupDataSource() {
88
+ this.cellRegistration = UICollectionViewCellRegistration.registrationWithCellClassConfigurationHandler(CollectionViewCell.class(), (view, indexPath, identifier) => {
89
+ const cell = view;
90
+ const templateType = this._getItemTemplateType(indexPath);
91
+ const firstRender = !cell.view;
92
+ if (Trace.isEnabled()) {
93
+ CLog(CLogTypes.log, 'collectionViewCellForItemAtIndexPath', indexPath.row, templateType, !!cell.view, cell);
94
+ }
95
+ this._prepareCell(cell, indexPath, templateType);
96
+ // the cell layout will be called from NSCellView layoutSubviews
97
+ const cellView = cell.view;
98
+ if (!firstRender && cellView['isLayoutRequired']) {
99
+ this.layoutCell(indexPath.row, cell, cellView);
100
+ }
101
+ return cell;
102
+ });
103
+ this._dataSource = UICollectionViewDiffableDataSource.alloc().initWithCollectionViewCellProvider(this.nativeView, (view, indexPath, identifier) => {
104
+ return this.nativeViewProtected.dequeueConfiguredReusableCellWithRegistrationForIndexPathItem(this.cellRegistration, indexPath, identifier);
105
+ });
106
+ this.setupHeaderFooter();
107
+ if (!this.sections) {
108
+ // every collectionview must have at least 1 section
109
+ this.sections = [{
110
+ identifier: getUUID(),
111
+ key: 'default'
112
+ }];
113
+ }
114
+ if (this.items?.length) {
115
+ this.refreshDataSourceSnapshot(this.getDefaultSectionIdentifier());
116
+ }
117
+ this.nativeView.dataSource = this._dataSource;
118
+ }
119
+ refreshDataSourceSnapshot(sectionIdentifier) {
120
+ if (this.items) {
121
+ this.modifyDataSourceSnapshot(ChangeType.Add, [], sectionIdentifier, false, true);
122
+ }
123
+ }
124
+ modifyDataSourceSnapshot(type, identifiers, sectionIdentifier, animate = true, reload = false) {
125
+ if (this.items) {
126
+ if (!this._dataSourceSnapshot || reload) {
127
+ this._dataSourceSnapshot = NSDiffableDataSourceSnapshot.alloc().init();
128
+ this._dataSourceSnapshot.appendSectionsWithIdentifiers(this.sections.map(s => s.identifier));
129
+ }
130
+ else {
131
+ this._dataSourceSnapshot = this._dataSource.snapshot();
132
+ }
133
+ if (Trace.isEnabled()) {
134
+ CLog(CLogTypes.info, 'modifyDataSourceSnapshot identifiers: ', type, identifiers);
135
+ }
136
+ // console.log('modifyDataSourceSnapshot identifiers: ', type, identifiers);
137
+ switch (type) {
138
+ case ChangeType.Add:
139
+ const itemIdentifiers = [];
140
+ if (reload) {
141
+ this.items.forEach(() => {
142
+ // forEach works well with ObservableArray and Array
143
+ itemIdentifiers.push(getUUID());
144
+ });
145
+ }
146
+ if (identifiers.length) {
147
+ itemIdentifiers.push(...identifiers);
148
+ }
149
+ if (sectionIdentifier) {
150
+ this._dataSourceSnapshot.appendItemsWithIdentifiersIntoSectionWithIdentifier(itemIdentifiers, sectionIdentifier);
151
+ }
152
+ else {
153
+ this._dataSourceSnapshot.appendItemsWithIdentifiers(itemIdentifiers);
154
+ }
155
+ break;
156
+ case ChangeType.Update:
157
+ this._dataSourceSnapshot.reloadItemsWithIdentifiers(identifiers);
158
+ break;
159
+ case ChangeType.Delete:
160
+ this._dataSourceSnapshot.deleteItemsWithIdentifiers(identifiers);
161
+ break;
162
+ }
163
+ this._dataSource.applySnapshotAnimatingDifferences(this._dataSourceSnapshot, animate);
164
+ }
165
+ }
166
+ getDefaultSectionIdentifier() {
167
+ // each collectionview must have at least 1 section
168
+ return this.sections[0].identifier;
169
+ }
170
+ setupHeaderFooter() {
171
+ if (!this.headerKey) {
172
+ // TODO: work on keyed header for multiple sections
173
+ this.headerKey = ViewTemplateType.Header;
174
+ }
175
+ if (this.headerItemTemplate) {
176
+ this.headerRegistration = UICollectionViewSupplementaryRegistration.registrationWithSupplementaryClassElementKindConfigurationHandler(CollectionViewCell.class(), this.headerKey, (cell, elementKind, indexPath) => {
177
+ this._prepareHeaderFooter(cell, indexPath, this.headerKey, ViewTemplateType.Header);
178
+ });
179
+ }
180
+ if (!this.footerKey) {
181
+ // TODO: work on keyed footer for multiple sections
182
+ this.footerKey = ViewTemplateType.Footer;
183
+ }
184
+ if (this.footerItemTemplate) {
185
+ this.footerRegistration = UICollectionViewSupplementaryRegistration.registrationWithSupplementaryClassElementKindConfigurationHandler(CollectionViewCell.class(), this.footerKey, (cell, elementKind, indexPath) => {
186
+ this._prepareHeaderFooter(cell, indexPath, this.footerKey, ViewTemplateType.Footer);
187
+ });
188
+ }
189
+ if (this.headerItemTemplate || this.footerItemTemplate) {
190
+ this._dataSource.supplementaryViewProvider = (view, elementKind, indexPath) => {
191
+ if (this.headerRegistration && elementKind == this.headerKey) {
192
+ return this.nativeViewProtected.dequeueConfiguredReusableSupplementaryViewWithRegistrationForIndexPath(this.headerRegistration, indexPath);
193
+ }
194
+ else if (this.footerRegistration) {
195
+ return this.nativeViewProtected.dequeueConfiguredReusableSupplementaryViewWithRegistrationForIndexPath(this.footerRegistration, indexPath);
196
+ }
197
+ };
198
+ }
199
+ }
94
200
  disposeNativeView() {
95
201
  if (Trace.isEnabled()) {
96
202
  CLog(CLogTypes.log, 'disposeNativeView');
@@ -365,122 +471,94 @@ export class CollectionView extends CollectionViewBase {
365
471
  if (Trace.isEnabled()) {
366
472
  CLog(CLogTypes.log, 'onItemsChanged', ChangeType.Update, event.action, event.index, event.addedCount, event.removed && event.removed.length);
367
473
  }
368
- // we need to clear stored cell sizes and it wont be correct anymore
369
- // this.clearCellSize();
370
- const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
474
+ // console.log('----')
475
+ // console.log('event.action:', event.action)
476
+ // console.log('event.addedCount:', event.addedCount);
477
+ // console.log('event.removed:', event.removed);
478
+ // console.log('event.index:', event.index)
479
+ // console.log(' >')
480
+ const sectionIdentifier = this._dataSource.sectionIdentifierForIndex(0);
481
+ // console.log(' sectionIdentifier:', sectionIdentifier)
371
482
  switch (event.action) {
372
483
  case ChangeType.Delete: {
373
- const indexes = NSMutableArray.new();
484
+ const identifiers = [];
374
485
  for (let index = 0; index < event.addedCount; index++) {
375
- indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
376
- if (sizes) {
377
- sizes.removeObjectAtIndex(event.index);
378
- }
486
+ const indexPath = NSIndexPath.indexPathForRowInSection(event.index + index, sectionIdentifier);
487
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath);
488
+ // console.log(' delete identifier:', identifier)
489
+ identifiers.push(identifier);
379
490
  }
380
- // this._sizes.splice(event.index, event.addedCount);
381
491
  this.unbindUnusedCells(event.removed);
382
- if (Trace.isEnabled()) {
383
- CLog(CLogTypes.info, 'deleteItemsAtIndexPaths', indexes.count);
384
- }
385
- view.performBatchUpdatesCompletion(() => {
386
- view.deleteItemsAtIndexPaths(indexes);
387
- }, null);
492
+ this.modifyDataSourceSnapshot(ChangeType.Delete, identifiers, sectionIdentifier);
388
493
  return;
389
494
  }
390
495
  case ChangeType.Update: {
391
- const indexes = NSMutableArray.new();
392
- indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index, 0));
393
- if (sizes) {
394
- sizes.replaceObjectAtIndexWithObject(event.index, NSValue.valueWithCGSize(CGSizeZero));
395
- }
396
- // this._sizes[event.index] = null;
397
- if (Trace.isEnabled()) {
398
- CLog(CLogTypes.info, 'reloadItemsAtIndexPaths', event.index, indexes.count);
399
- }
400
- view.performBatchUpdatesCompletion(() => {
401
- view.reloadItemsAtIndexPaths(indexes);
402
- }, null);
496
+ const identifiers = [];
497
+ const indexPath = NSIndexPath.indexPathForRowInSection(event.index, sectionIdentifier);
498
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath);
499
+ // console.log(' update identifier:', identifier)
500
+ identifiers.push(identifier);
501
+ this.modifyDataSourceSnapshot(ChangeType.Update, identifiers, sectionIdentifier);
403
502
  return;
404
503
  }
405
504
  case ChangeType.Add: {
406
- const indexes = NSMutableArray.new();
505
+ const identifiers = [];
407
506
  for (let index = 0; index < event.addedCount; index++) {
408
- indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
409
- if (sizes) {
410
- sizes.insertObjectAtIndex(NSValue.valueWithCGSize(CGSizeZero), event.index);
411
- }
412
- // this._sizes.splice(index, 0, null);
507
+ const indexPath = NSIndexPath.indexPathForRowInSection(event.index + index, sectionIdentifier);
508
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath) || getUUID();
509
+ // console.log(' add identifier:', identifier)
510
+ identifiers.push(identifier);
413
511
  }
414
- if (Trace.isEnabled()) {
415
- CLog(CLogTypes.info, 'insertItemsAtIndexPaths', indexes.count);
416
- }
417
- view.performBatchUpdatesCompletion(() => {
418
- view.insertItemsAtIndexPaths(indexes);
419
- }, null);
512
+ this.modifyDataSourceSnapshot(ChangeType.Add, identifiers, sectionIdentifier);
420
513
  return;
421
514
  }
422
515
  case ChangeType.Splice: {
423
- view.performBatchUpdatesCompletion(() => {
424
- const added = event.addedCount;
425
- const removed = (event.removed && event.removed.length) || 0;
426
- if (added > 0 && added === removed) {
427
- const indexes = NSMutableArray.new();
428
- for (let index = 0; index < added; index++) {
429
- indexes.addObject(NSIndexPath.indexPathForRowInSection(event.index + index, 0));
430
- if (sizes) {
431
- sizes.replaceObjectAtIndexWithObject(event.index + index, NSValue.valueWithCGSize(CGSizeZero));
432
- }
433
- // this._sizes[event.index + index] = null;
434
- }
435
- view.reloadItemsAtIndexPaths(indexes);
516
+ const added = event.addedCount;
517
+ const removed = (event.removed && event.removed.length) || 0;
518
+ if (added > 0 && added === removed) {
519
+ const identifiers = [];
520
+ for (let index = 0; index < added; index++) {
521
+ const indexPath = NSIndexPath.indexPathForRowInSection(event.index + index, sectionIdentifier);
522
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath) || getUUID();
523
+ // console.log(' splice, update identifier:', identifier)
524
+ identifiers.push(identifier);
436
525
  }
437
- else {
438
- if (event.removed && event.removed.length > 0) {
439
- const indexes = NSMutableArray.new();
440
- for (let index = 0; index < event.removed.length; index++) {
441
- indexes.addObject(NSIndexPath.indexPathForItemInSection(event.index + index, 0));
442
- if (sizes) {
443
- sizes.removeObjectAtIndex(event.index);
444
- }
445
- }
446
- // this._sizes.splice(event.index, event.removed.length);
447
- this.unbindUnusedCells(event.removed);
448
- if (Trace.isEnabled()) {
449
- CLog(CLogTypes.info, 'deleteItemsAtIndexPaths', indexes.count);
450
- }
451
- view.deleteItemsAtIndexPaths(indexes);
526
+ this.modifyDataSourceSnapshot(ChangeType.Update, identifiers, sectionIdentifier);
527
+ }
528
+ else {
529
+ if (event.removed && event.removed.length > 0) {
530
+ const identifiers = [];
531
+ for (let index = 0; index < event.removed.length; index++) {
532
+ const indexPath = NSIndexPath.indexPathForItemInSection(event.index + index, sectionIdentifier);
533
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath);
534
+ // console.log(' splice, remove identifier:', identifier)
535
+ identifiers.push(identifier);
452
536
  }
453
- if (event.addedCount > 0) {
454
- const indexes = NSMutableArray.alloc().init();
455
- for (let index = 0; index < event.addedCount; index++) {
456
- indexes.addObject(NSIndexPath.indexPathForItemInSection(event.index + index, 0));
457
- if (sizes) {
458
- sizes.insertObjectAtIndex(NSValue.valueWithCGSize(CGSizeZero), event.index);
459
- }
460
- // this._sizes.splice(event.index, 0, null);
461
- }
462
- if (Trace.isEnabled()) {
463
- CLog(CLogTypes.info, 'insertItemsAtIndexPaths', indexes.count);
464
- }
465
- view.insertItemsAtIndexPaths(indexes);
537
+ this.unbindUnusedCells(event.removed);
538
+ this.modifyDataSourceSnapshot(ChangeType.Delete, identifiers, sectionIdentifier);
539
+ }
540
+ if (event.addedCount > 0) {
541
+ const identifiers = [];
542
+ for (let index = 0; index < event.addedCount; index++) {
543
+ const indexPath = NSIndexPath.indexPathForItemInSection(event.index + index, sectionIdentifier);
544
+ const identifier = this._dataSource.itemIdentifierForIndexPath(indexPath) || getUUID();
545
+ // console.log(' splice, add identifier:', identifier)
546
+ identifiers.push(identifier);
466
547
  }
548
+ this.modifyDataSourceSnapshot(ChangeType.Add, identifiers, sectionIdentifier);
467
549
  }
468
- // view.collectionViewLayout.invalidateLayout();
469
- }, null);
550
+ }
551
+ // view.collectionViewLayout.invalidateLayout();
470
552
  return;
471
553
  }
472
554
  }
473
555
  this.refresh();
474
556
  }
475
- onItemTemplatesChanged(oldValue, newValue) {
476
- super.onItemTemplatesChanged(oldValue, newValue);
477
- if (!this.nativeViewProtected) {
478
- return;
479
- }
480
- const view = this.nativeViewProtected;
481
- this._itemTemplatesInternal.forEach((t) => {
482
- view.registerClassForCellWithReuseIdentifier(CollectionViewCell.class(), t.key.toLowerCase());
483
- });
557
+ clearEmbeddedViews() {
558
+ this.clearRealizedCells();
559
+ // if (this.itemViewDisposer !== undefined) {
560
+ // this.itemViewDisposer();
561
+ // }
484
562
  }
485
563
  unbindUnusedCells(removedDataItems) {
486
564
  this._map.forEach((view, nativeView, map) => {
@@ -497,14 +575,7 @@ export class CollectionView extends CollectionViewBase {
497
575
  if (!view) {
498
576
  return;
499
577
  }
500
- const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
501
578
  const visibles = view.indexPathsForVisibleItems;
502
- if (sizes?.count) {
503
- const indexes = Array.from(visibles);
504
- indexes.forEach((value) => {
505
- sizes.replaceObjectAtIndexWithObject(value.row, NSValue.valueWithCGSize(CGSizeZero));
506
- });
507
- }
508
579
  UIView.performWithoutAnimation(() => {
509
580
  view.performBatchUpdatesCompletion(() => {
510
581
  view.reloadItemsAtIndexPaths(visibles);
@@ -529,18 +600,13 @@ export class CollectionView extends CollectionViewBase {
529
600
  if (Trace.isEnabled()) {
530
601
  CLog(CLogTypes.info, 'refresh');
531
602
  }
532
- // we need to clear stored cell sizes and it wont be correct anymore
533
- // this.clearCellSize();
534
- const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
535
- if (sizes) {
536
- sizes.removeAllObjects();
537
- }
538
603
  // clear bindingContext when it is not observable because otherwise bindings to items won't reevaluate
539
604
  this._map.forEach((view, nativeView, map) => {
540
605
  if (!(view.bindingContext instanceof Observable)) {
541
606
  view.bindingContext = null;
542
607
  }
543
608
  });
609
+ this.refreshDataSourceSnapshot(this.getDefaultSectionIdentifier());
544
610
  // TODO: this is ugly look here: https://github.com/nativescript-vue/nativescript-vue/issues/525
545
611
  // this.clearRealizedCells();
546
612
  // dispatch_async(main_queue, () => {
@@ -584,10 +650,62 @@ export class CollectionView extends CollectionViewBase {
584
650
  }
585
651
  return type.toLowerCase();
586
652
  }
587
- getItemTemplateContent(index, templateType) {
588
- return this.getViewForViewType(ListViewViewTypes.ItemView, templateType);
653
+ disableIosOverflowSafeArea(parentView) {
654
+ if (parentView) {
655
+ parentView.iosOverflowSafeAreaEnabled = false;
656
+ }
657
+ }
658
+ _prepareHeaderFooter(cell, indexPath, templateKey, templateType, notForCellSizeComp = true) {
659
+ let cellSize;
660
+ try {
661
+ this._preparingCell = true;
662
+ const firstRender = !cell.view;
663
+ let view = cell.view;
664
+ const index = indexPath.row;
665
+ if (!view) {
666
+ view = this.getViewForTemplateType(templateKey, templateType);
667
+ }
668
+ if (Trace.isEnabled()) {
669
+ CLog(CLogTypes.log, '_prepareHeaderFooter', index, templateType, !!cell.view, !!view, cell.view !== view, notForCellSizeComp);
670
+ }
671
+ if (view) {
672
+ if (firstRender) {
673
+ view['iosIgnoreSafeArea'] = true;
674
+ }
675
+ view.bindingContext = this.bindingContext;
676
+ if (view instanceof ProxyViewContainer) {
677
+ const sp = new ContentView();
678
+ sp.content = view;
679
+ view = sp;
680
+ }
681
+ if (!cell.view) {
682
+ cell.owner = new WeakRef(view);
683
+ }
684
+ else if (cell.view !== view) {
685
+ this._removeContainer(cell);
686
+ if (cell.view?.nativeViewProtected) {
687
+ cell.view.nativeViewProtected.removeFromSuperview();
688
+ }
689
+ cell.owner = new WeakRef(view);
690
+ }
691
+ cell.currentIndex = indexPath.row;
692
+ if (view && !view.parent) {
693
+ this._addView(view);
694
+ const innerView = NSCellView.new();
695
+ innerView.autoresizingMask = 2 /* UIViewAutoresizing.FlexibleWidth */ | 16 /* UIViewAutoresizing.FlexibleHeight */;
696
+ innerView.view = new WeakRef(view);
697
+ innerView.addSubview(view.nativeViewProtected);
698
+ cell.addSubview(innerView);
699
+ }
700
+ cellSize = this.measureCell(cell, view, indexPath.row);
701
+ }
702
+ }
703
+ finally {
704
+ this._preparingCell = false;
705
+ }
706
+ return cellSize;
589
707
  }
590
- _prepareCell(cell, indexPath, templateType, notForCellSizeComp = true) {
708
+ _prepareCell(cell, indexPath, templateKey, notForCellSizeComp = true) {
591
709
  let cellSize;
592
710
  try {
593
711
  this._preparingCell = true;
@@ -595,11 +713,11 @@ export class CollectionView extends CollectionViewBase {
595
713
  let view = cell.view;
596
714
  const index = indexPath.row;
597
715
  if (!view) {
598
- view = this.getItemTemplateContent(index, templateType);
716
+ view = this.getViewForTemplateType(templateKey);
599
717
  }
600
718
  const bindingContext = this._prepareItem(view, index);
601
719
  if (Trace.isEnabled()) {
602
- CLog(CLogTypes.log, '_prepareCell', index, templateType, !!cell.view, !!view, cell.view !== view, notForCellSizeComp);
720
+ CLog(CLogTypes.log, '_prepareCell', index, templateKey, !!cell.view, !!view, cell.view !== view, notForCellSizeComp);
603
721
  }
604
722
  const args = this.notifyForItemAtIndex(CollectionViewBase.itemLoadingEvent, view, indexPath.row, bindingContext, cell);
605
723
  view = args.view;
@@ -617,7 +735,9 @@ export class CollectionView extends CollectionViewBase {
617
735
  }
618
736
  else if (cell.view !== view) {
619
737
  this._removeContainer(cell);
620
- cell.view.nativeViewProtected.removeFromSuperview();
738
+ if (cell.view?.nativeViewProtected) {
739
+ cell.view.nativeViewProtected.removeFromSuperview();
740
+ }
621
741
  cell.owner = new WeakRef(view);
622
742
  }
623
743
  cell.currentIndex = indexPath.row;
@@ -629,25 +749,21 @@ export class CollectionView extends CollectionViewBase {
629
749
  const innerView = NSCellView.new();
630
750
  innerView.autoresizingMask = 2 /* UIViewAutoresizing.FlexibleWidth */ | 16 /* UIViewAutoresizing.FlexibleHeight */;
631
751
  innerView.view = new WeakRef(view);
632
- if (notForCellSizeComp && this.autoReloadItemOnLayout) {
633
- // for a cell to update correctly on cell layout change we need
634
- // to do it ourself instead of "propagating it"
635
- view['performLayout'] = () => {
636
- if (!this._preparingCell) {
637
- const index = cell.currentIndex;
638
- const nativeView = this.nativeViewProtected;
639
- const sizes = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
640
- if (sizes) {
641
- sizes.replaceObjectAtIndexWithObject(index, NSValue.valueWithCGSize(CGSizeZero));
642
- }
643
- nativeView.performBatchUpdatesCompletion(() => {
644
- this.measureCell(cell, view, index);
645
- this.notifyForItemAtIndex(CollectionViewBase.itemLoadingEvent, view, indexPath.row, view.bindingContext, cell);
646
- }, null);
647
- nativeView.collectionViewLayout.invalidateLayout();
648
- }
649
- };
650
- }
752
+ // if (notForCellSizeComp && this.autoReloadItemOnLayout) {
753
+ // // for a cell to update correctly on cell layout change we need
754
+ // // to do it ourself instead of "propagating it"
755
+ // view['performLayout'] = () => {
756
+ // if (!this._preparingCell) {
757
+ // const index = cell.currentIndex;
758
+ // const nativeView = this.nativeViewProtected;
759
+ // nativeView.performBatchUpdatesCompletion(() => {
760
+ // this.measureCell(cell, view, index);
761
+ // this.notifyForItemAtIndex(CollectionViewBase.itemLoadingEvent, view, indexPath.row, view.bindingContext, cell);
762
+ // }, null);
763
+ // nativeView.collectionViewLayout.invalidateLayout();
764
+ // }
765
+ // };
766
+ // }
651
767
  innerView.addSubview(view.nativeViewProtected);
652
768
  cell.contentView.addSubview(innerView);
653
769
  }
@@ -665,7 +781,6 @@ export class CollectionView extends CollectionViewBase {
665
781
  return cellSize;
666
782
  }
667
783
  getCellSize(index) {
668
- // let result = this._sizes[index];
669
784
  let result;
670
785
  // CLog(CLogTypes.log, 'getCellSize', index, result, this._effectiveColWidth, this._effectiveRowHeight, this.getMeasuredWidth(), this.getMeasuredHeight());
671
786
  if (!result) {
@@ -695,12 +810,6 @@ export class CollectionView extends CollectionViewBase {
695
810
  // return undefined;
696
811
  return result;
697
812
  }
698
- // public storeCellSize(index: number, value) {
699
- // this._sizes[index] = value;
700
- // }
701
- // public clearCellSize() {
702
- // this._sizes = new Array<number[]>();
703
- // }
704
813
  measureCell(cell, cellView, position) {
705
814
  if (cellView) {
706
815
  let width = this._effectiveColWidth;
@@ -811,6 +920,28 @@ export class CollectionView extends CollectionViewBase {
811
920
  }
812
921
  return cell;
813
922
  }
923
+ // collectionViewViewForSupplementaryElementOfKindAtIndexPath(view: UICollectionView, kind: string, indexPath: NSIndexPath): UICollectionReusableView {
924
+ // // const templateType = kind === UICollectionElementKindSectionHeader ? this._headerTemplate.key : this._footerTemplate.key;
925
+ // const templateType = kind;
926
+ // console.log('templateType:', templateType)
927
+ // // let cell = collectionView.dequeueConfiguredReusableSupplementaryViewWithRegistrationForIndexPath(kind, templateType, indexPath) as CollectionViewReusableView;
928
+ // let cell = this._dataSource.supplementaryViewProvider(view, kind, indexPath);
929
+ // console.log('cell:', cell)
930
+ // // if (!cell) {
931
+ // // cell = CollectionViewReusableView.new() as CollectionViewReusableView;
932
+ // // }
933
+ // // const firstRender = !cell.view;
934
+ // // if (Trace.isEnabled()) {
935
+ // // CLog(CLogTypes.log, 'collectionViewViewForSupplementaryElementOfKindAtIndexPath', indexPath.row, templateType, !!cell.view, cell);
936
+ // // }
937
+ // // this._prepareHeaderFooter(cell, indexPath, templateType);
938
+ // // the cell layout will be called from NSCellView layoutSubviews
939
+ // // const cellView: View = cell.view;
940
+ // // if (!firstRender && cellView['isLayoutRequired']) {
941
+ // // this.layoutCell(indexPath.row, cell, cellView);
942
+ // // }
943
+ // return cell;
944
+ // }
814
945
  collectionViewWillDisplayCellForItemAtIndexPath(collectionView, cell, indexPath) {
815
946
  if (this.reverseLayout) {
816
947
  cell.transform = CGAffineTransformMakeRotation(-Math.PI);
@@ -1005,66 +1136,20 @@ var CollectionViewCell = /** @class */ (function (_super) {
1005
1136
  };
1006
1137
  return CollectionViewCell;
1007
1138
  }(UICollectionViewCell));
1008
- var CollectionViewDataSource = /** @class */ (function (_super) {
1009
- __extends(CollectionViewDataSource, _super);
1010
- function CollectionViewDataSource() {
1139
+ var CollectionViewReusableView = /** @class */ (function (_super) {
1140
+ __extends(CollectionViewReusableView, _super);
1141
+ function CollectionViewReusableView() {
1011
1142
  return _super !== null && _super.apply(this, arguments) || this;
1012
1143
  }
1013
- CollectionViewDataSource.initWithOwner = function (owner) {
1014
- var delegate = CollectionViewDataSource.new();
1015
- delegate._owner = new WeakRef(owner);
1016
- return delegate;
1017
- };
1018
- CollectionViewDataSource.prototype.numberOfSectionsInCollectionView = function (collectionView) {
1019
- var owner = this._owner.deref();
1020
- if (owner) {
1021
- return owner.numberOfSectionsInCollectionView(collectionView);
1022
- }
1023
- return 0;
1024
- };
1025
- CollectionViewDataSource.prototype.collectionViewNumberOfItemsInSection = function (collectionView, section) {
1026
- var owner = this._owner.deref();
1027
- if (owner) {
1028
- return owner.collectionViewNumberOfItemsInSection(collectionView, section);
1029
- }
1030
- return 0;
1031
- };
1032
- CollectionViewDataSource.prototype.collectionViewCellForItemAtIndexPath = function (collectionView, indexPath) {
1033
- var owner = this._owner.deref();
1034
- if (owner) {
1035
- return owner.collectionViewCellForItemAtIndexPath(collectionView, indexPath);
1036
- }
1037
- return null;
1038
- };
1039
- CollectionViewDataSource.prototype.collectionViewMoveItemAtIndexPathToIndexPath = function (collectionView, sourceIndexPath, destinationIndexPath) {
1040
- var owner = this._owner.deref();
1041
- if (owner) {
1042
- owner.reorderStartingRow = sourceIndexPath.row;
1043
- owner.reorderEndingRow = destinationIndexPath.row;
1044
- owner._reorderItemInSource(sourceIndexPath.row, destinationIndexPath.row, false);
1045
- }
1046
- };
1047
- CollectionViewDataSource.prototype.collectionViewTargetIndexPathForMoveFromItemAtIndexPathToProposedIndexPath = function (collectionView, originalIndexPath, proposedIndexPath) {
1048
- var owner = this._owner.deref();
1049
- if (owner) {
1050
- owner.reorderEndingRow = proposedIndexPath.row;
1051
- }
1052
- return proposedIndexPath;
1053
- };
1054
- CollectionViewDataSource.prototype.collectionViewCanMoveItemAtIndexPath = function (collectionView, indexPath) {
1055
- var owner = this._owner.deref();
1056
- if (owner) {
1057
- var result = owner.shouldMoveItemAtIndex(indexPath.row);
1058
- if (result) {
1059
- owner.reorderStartingRow = indexPath.row;
1060
- }
1061
- return result;
1062
- }
1063
- return false;
1064
- };
1065
- CollectionViewDataSource.ObjCProtocols = [UICollectionViewDataSource];
1066
- return CollectionViewDataSource;
1067
- }(NSObject));
1144
+ Object.defineProperty(CollectionViewReusableView.prototype, "view", {
1145
+ get: function () {
1146
+ return this.owner ? this.owner.deref() : null;
1147
+ },
1148
+ enumerable: true,
1149
+ configurable: true
1150
+ });
1151
+ return CollectionViewReusableView;
1152
+ }(UICollectionReusableView));
1068
1153
  var UICollectionViewDelegateImpl = /** @class */ (function (_super) {
1069
1154
  __extends(UICollectionViewDelegateImpl, _super);
1070
1155
  function UICollectionViewDelegateImpl() {