Skip to content

Commit bd71225

Browse files
committed
fix(ios): much faster cells layout + improved autoReloadItemOnLayout
1 parent 10fcf59 commit bd71225

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/collectionview/index.ios.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ export class CollectionView extends CollectionViewBase {
444444
if (Trace.isEnabled()) {
445445
CLog(CLogTypes.info, 'reloadItemsAtIndexPaths', event.index, indexes.count);
446446
}
447+
// TODO: for now we dont animate to be like android
447448
UIView.performWithoutAnimation(() => {
448449
view.performBatchUpdatesCompletion(() => {
449450
view.reloadItemsAtIndexPaths(indexes);
@@ -674,6 +675,7 @@ export class CollectionView extends CollectionViewBase {
674675
cell.view.nativeViewProtected.removeFromSuperview();
675676
cell.owner = new WeakRef(view);
676677
}
678+
cell.currentIndex = indexPath.row;
677679

678680
if (notForCellSizeComp) {
679681
this._map.set(cell, view);
@@ -682,22 +684,34 @@ export class CollectionView extends CollectionViewBase {
682684
if (view && !view.parent) {
683685
this._addView(view);
684686
const innerView = NSCellView.new() as NSCellView;
687+
innerView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
685688
innerView.view = new WeakRef(view);
686-
if (!notForCellSizeComp || this.autoReloadItemOnLayout) {
689+
if (notForCellSizeComp && this.autoReloadItemOnLayout) {
687690
// for a cell to update correctly on cell layout change we need
688691
// to do it ourself instead of "propagating it"
689692
view['performLayout'] = () => {
690-
if (notForCellSizeComp) {
691-
this.measureCell(cell, view, indexPath);
692-
this.layoutCell(indexPath.row, cell, view);
693+
if (!this._preparingCell) {
694+
const nativeView = this.nativeViewProtected;
695+
const sizes: NSMutableArray<NSValue> = this._delegate instanceof UICollectionViewDelegateImpl ? this._delegate.cachedSizes : null;
696+
if (sizes) {
697+
sizes.replaceObjectAtIndexWithObject(cell.currentIndex, NSValue.valueWithCGSize(CGSizeZero));
698+
}
699+
// TODO: for now we dont animate to be like android
700+
UIView.performWithoutAnimation(() => {
701+
nativeView.performBatchUpdatesCompletion(() => {
702+
this.measureCell(cell, view, cell.currentIndex);
703+
// this.layoutCell(indexPath.row, cell, view);
704+
// cell.layoutIfNeeded();
705+
}, null);
706+
});
693707
this.nativeViewProtected.collectionViewLayout.invalidateLayout();
694708
}
695709
};
696710
}
697711
innerView.addSubview(view.nativeViewProtected);
698712
cell.contentView.addSubview(innerView);
699713
}
700-
cellSize = this.measureCell(cell, view, indexPath);
714+
cellSize = this.measureCell(cell, view, indexPath.row);
701715
if (notForCellSizeComp) {
702716
view.notify({ eventName: CollectionViewBase.bindedEvent });
703717
}
@@ -745,13 +759,12 @@ export class CollectionView extends CollectionViewBase {
745759
// public clearCellSize() {
746760
// this._sizes = new Array<number[]>();
747761
// }
748-
private measureCell(cell: CollectionViewCell, cellView: View, index: NSIndexPath): [number, number] {
762+
private measureCell(cell: CollectionViewCell, cellView: View, position: number): [number, number] {
749763
if (cellView) {
750764
let width = this._effectiveColWidth;
751765
let height = this._effectiveRowHeight;
752766
const horizontal = this.isHorizontal();
753767
if (this.spanSize) {
754-
const position = index.row;
755768
const dataItem = this.getItemAtIndex(position);
756769
const spanSize = this.spanSize(dataItem, position);
757770
if (horizontal) {
@@ -772,7 +785,7 @@ export class CollectionView extends CollectionViewBase {
772785
? Utils.layout.makeMeasureSpec(this._innerHeight, Utils.layout.UNSPECIFIED)
773786
: infinity;
774787
if (Trace.isEnabled()) {
775-
CLog(CLogTypes.log, 'measureCell', index.row, width, height, widthMeasureSpec, heightMeasureSpec);
788+
CLog(CLogTypes.log, 'measureCell', position, width, height, widthMeasureSpec, heightMeasureSpec);
776789
}
777790
const measuredSize = View.measureChild(this, cellView, widthMeasureSpec, heightMeasureSpec);
778791
const result: [number, number] = [measuredSize.measuredWidth, measuredSize.measuredHeight];
@@ -851,6 +864,8 @@ export class CollectionView extends CollectionViewBase {
851864
collectionViewCellForItemAtIndexPath(collectionView: UICollectionView, indexPath: NSIndexPath): UICollectionViewCell {
852865
const templateType = this._getItemTemplateType(indexPath);
853866
let cell = collectionView.dequeueReusableCellWithReuseIdentifierForIndexPath(templateType, indexPath) as CollectionViewCell;
867+
868+
const firstRender = !cell.view;
854869
if (!cell) {
855870
cell = CollectionViewCell.new() as CollectionViewCell;
856871
}
@@ -860,10 +875,12 @@ export class CollectionView extends CollectionViewBase {
860875
this._prepareCell(cell, indexPath, templateType);
861876

862877
// the cell layout will be called from NSCellView layoutSubviews
863-
const cellView: View = cell.view;
864-
if (cellView['isLayoutRequired']) {
865-
this.layoutCell(indexPath.row, cell, cellView);
866-
}
878+
// const cellView: View = cell.view;
879+
// if (!firstRender && cellView['isLayoutRequired']) {
880+
// cell.setNeedsLayout();
881+
// cell.layoutSubviews();
882+
// this.layoutCell(indexPath.row, cell, cellView);
883+
// }
867884
return cell;
868885
}
869886
collectionViewWillDisplayCellForItemAtIndexPath(collectionView: UICollectionView, cell: UICollectionViewCell, indexPath: NSIndexPath) {
@@ -1023,6 +1040,7 @@ class NSCellView extends UIView {
10231040
@NativeClass
10241041
class CollectionViewCell extends UICollectionViewCell {
10251042
owner: WeakRef<ItemView>;
1043+
currentIndex: number;
10261044

10271045
get view(): ItemView {
10281046
return this.owner ? this.owner.get() : null;

0 commit comments

Comments
 (0)