@nativescript-community/ui-pager
Version:
A NativeScript Pager / Carousel component that allows the user to swipe left and right through pages of data.
1,162 lines (1,161 loc) • 53.2 kB
JavaScript
import { ChangeType, Observable, Property, ProxyViewContainer, StackLayout, Utils, View, profile } from '@nativescript/core';
import { paddingBottomProperty, paddingLeftProperty, paddingRightProperty, paddingTopProperty } from '@nativescript/core/ui/styling/style-properties';
import { PagerBase, autoPlayProperty, autoplayDelayProperty, disableSwipeProperty, itemTemplatesProperty, itemsProperty, orientationProperty, selectedIndexProperty } from './index.common';
export * from './index.common';
export { Transformer } from './index.common';
const main_queue = dispatch_get_current_queue();
export var ContentInsetAdjustmentBehavior;
(function (ContentInsetAdjustmentBehavior) {
ContentInsetAdjustmentBehavior[ContentInsetAdjustmentBehavior["Always"] = 3] = "Always";
ContentInsetAdjustmentBehavior[ContentInsetAdjustmentBehavior["Automatic"] = 0] = "Automatic";
ContentInsetAdjustmentBehavior[ContentInsetAdjustmentBehavior["Never"] = 2] = "Never";
ContentInsetAdjustmentBehavior[ContentInsetAdjustmentBehavior["ScrollableAxes"] = 1] = "ScrollableAxes";
})(ContentInsetAdjustmentBehavior || (ContentInsetAdjustmentBehavior = {}));
function parseContentInsetAdjustmentBehavior(value) {
if (typeof value === 'string') {
switch (value) {
case 'always':
return ContentInsetAdjustmentBehavior.Always;
case 'never':
return ContentInsetAdjustmentBehavior.Never;
case 'scrollableAxes':
return ContentInsetAdjustmentBehavior.ScrollableAxes;
default:
case 'automatic':
return ContentInsetAdjustmentBehavior.Automatic;
}
}
else {
return value;
}
}
export const contentInsetAdjustmentBehaviorProperty = new Property({
name: 'contentInsetAdjustmentBehavior',
valueConverter: parseContentInsetAdjustmentBehavior,
defaultValue: ContentInsetAdjustmentBehavior.Automatic
});
var UICellView = /** @class */ (function (_super) {
__extends(UICellView, _super);
function UICellView() {
return _super !== null && _super.apply(this, arguments) || this;
}
UICellView.prototype.layoutSubviews = function () {
var view = this.view && this.view.get();
if (!view) {
return;
}
this.frame = this.superview.bounds;
var size = this.bounds.size;
View.layoutChild(null, view, 0, 0, Utils.layout.toDevicePixels(size.width), Utils.layout.toDevicePixels(size.height));
};
return UICellView;
}(UIView));
const PFLAG_FORCE_LAYOUT = 1;
export class Pager extends PagerBase {
constructor() {
super();
this.lastEvent = 0;
this.mDisableSwipe = false;
this.mDisableAnimation = false;
this.mPreparingCell = false;
this.mIsRefreshing = false;
this.mIsInit = false;
this._observableArrayHandler = (args) => {
if (!this.nativeViewProtected) {
return;
}
if (this.indicator && this.mObservableArrayInstance && this.mObservableArrayInstance.length) {
this.indicator.setCount(this.mObservableArrayInstance.length);
}
const collectionView = this.nativeViewProtected;
if (collectionView) {
try {
let offset = 0;
collectionView.performBatchUpdatesCompletion(() => {
this.mIsRefreshing = true;
const array = [];
switch (args.action) {
case ChangeType.Add:
for (let i = 0; i < args.addedCount; i++) {
array.push(NSIndexPath.indexPathForRowInSection(args.index + i, 0));
}
offset = collectionView.contentSize.width - collectionView.contentOffset.x;
collectionView.insertItemsAtIndexPaths(array);
break;
case ChangeType.Delete:
for (let i = 0; i < args.removed.length; i++) {
array.push(NSIndexPath.indexPathForItemInSection(args.index + i, 0));
}
collectionView.deleteItemsAtIndexPaths(array);
break;
case ChangeType.Splice:
if (args.removed && args.removed.length > 0) {
for (let i = 0; i < args.removed.length; i++) {
array.push(NSIndexPath.indexPathForRowInSection(args.index + i, 0));
}
collectionView.deleteItemsAtIndexPaths(array);
}
if (args.addedCount > 0) {
const addedArray = [];
for (let i = 0; i < args.addedCount; i++) {
addedArray.push(NSIndexPath.indexPathForRowInSection(args.index + i, 0));
}
collectionView.insertItemsAtIndexPaths(addedArray);
}
break;
case ChangeType.Update:
collectionView.reloadItemsAtIndexPaths([NSIndexPath.indexPathForRowInSection(args.index, 0)]);
break;
default:
break;
}
this._initAutoPlay(this.autoPlay);
if (this.itemCount === 0) {
this.mIsInit = false;
selectedIndexProperty.nativeValueChange(this, -1);
}
}, () => {
if (collectionView.indexPathsForVisibleItems.count > 0) {
const currentIndex = collectionView.indexPathsForVisibleItems.objectAtIndex(0).item;
selectedIndexProperty.nativeValueChange(this, this.getPosition(currentIndex));
}
});
}
catch (err) { }
}
};
this._isDataDirty = false;
this.mMap = new Map();
}
createNativeView() {
this.mLayout = UICollectionViewFlowLinearLayoutImpl.initWithOwner(new WeakRef(this));
this.mLayout.scrollDirection = 1 /* UICollectionViewScrollDirection.Horizontal */;
this.mLayout.minimumInteritemSpacing = 0;
const nativeView = UICollectionView.alloc().initWithFrameCollectionViewLayout(CGRectZero, this.mLayout);
nativeView.backgroundColor = UIColor.clearColor;
nativeView.autoresizesSubviews = false;
nativeView.autoresizingMask = 0 /* UIViewAutoresizing.None */;
nativeView.showsHorizontalScrollIndicator = false;
nativeView.showsVerticalScrollIndicator = false;
nativeView.decelerationRate = UIScrollViewDecelerationRateFast;
this._itemTemplatesInternal.forEach((t) => {
nativeView.registerClassForCellWithReuseIdentifier(PagerCell.class(), t.key);
});
return nativeView;
}
initNativeView() {
super.initNativeView();
const nativeView = this.nativeViewProtected;
nativeView.registerClassForCellWithReuseIdentifier(PagerCell.class(), this._defaultTemplate.key);
nativeView.backgroundColor = UIColor.clearColor;
nativeView.autoresizesSubviews = false;
nativeView.autoresizingMask = 0;
nativeView.dataSource = this.mDataSource = UICollectionViewDataSourceImpl.initWithOwner(new WeakRef(this));
nativeView.scrollEnabled = !this.disableSwipe;
if (this.orientation === 'vertical') {
this.mLayout.scrollDirection = 0 /* UICollectionViewScrollDirection.Vertical */;
nativeView.alwaysBounceVertical = true;
nativeView.alwaysBounceHorizontal = false;
}
else {
this.mLayout.scrollDirection = 1 /* UICollectionViewScrollDirection.Horizontal */;
nativeView.alwaysBounceHorizontal = true;
nativeView.alwaysBounceVertical = false;
}
this.mDelegate = UICollectionDelegateImpl.initWithOwner(new WeakRef(this));
this._setNativeClipToBounds();
this._initAutoPlay(this.autoPlay);
}
getChildView(index) {
if (this._childrenViews) {
return this._childrenViews[index]?.view;
}
let result;
if (this.nativeViewProtected) {
const cell = this.nativeViewProtected.cellForItemAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
return cell?.view;
}
return result;
}
getViewForItemAtIndex(index) {
return this.getChildView(index);
}
_getRealWidthHeight() {
let height = 0;
let width = 0;
width = (Utils.layout.toDeviceIndependentPixels(this._effectiveItemWidth) - (this.perPage * 2 * this._getSpacing() + this._getPeaking() * 2)) / this.perPage;
height = (Utils.layout.toDeviceIndependentPixels(this._effectiveItemHeight) - (this.perPage * 2 * this._getSpacing() + this._getPeaking() * 2)) / this.perPage;
return { height, width };
}
_nextIndex() {
if (this.circularMode) {
// TODO
return 0;
}
else {
const next = this.selectedIndex + 1;
if (next > this.lastIndex) {
return 0;
}
return next;
}
}
_initAutoPlay(value) {
if (!this.items || this.items.length === 0) {
return;
}
if (!value) {
if (this._autoPlayInterval) {
clearInterval(this._autoPlayInterval);
this._autoPlayInterval = undefined;
}
}
else {
if (this.isLayoutValid && !this._autoPlayInterval) {
this._autoPlayInterval = setInterval(() => {
this.selectedIndex = this._nextIndex();
}, this.autoPlayDelay);
}
}
}
/**
*
* Get the selected index from the position in the CollectionView
*
* @param index The position in the collectionView
* @returns The selected Index ( i.e. the number in the slides as the user would view it).
*/
getPosition(index) {
let position = index;
if (this.circularMode) {
if (position === 0) {
position = this.lastDummy;
}
else if (position === this.firstDummy) {
position = 0;
}
else {
position = position - 1;
}
}
return position;
}
/**
*
* Get the position in the CollectionView from the selected index
*
* @param index The position in the collectionView
* @returns The selected Index ( i.e. the number in the slides as the user would view it).
*/
getIndex(index) {
let position = index;
if (this.circularMode) {
if (position === 0) {
position = 1;
}
else if (position === this.firstDummy) {
position = 0;
}
else {
position = position + 1;
}
}
return position;
}
animateForFlip(index) {
if (!this.circularMode) {
return true;
}
if (index !== this.firstDummy && index !== 0) {
return true;
}
return false;
}
get itemCount() {
return this._childrenCount ? this._childrenCount + (this.circularMode ? 2 : 0) : 0;
}
get lastIndex() {
return Math.max(0, this.circularMode ? this.itemCount - 3 : this.itemCount - 1);
}
get firstDummy() {
return Math.max(0, this.itemCount - 1);
}
get lastDummy() {
return this.lastIndex;
}
get _childrenCount() {
return this.items?.length ?? this._childrenViews?.length ?? 0;
}
itemTemplateUpdated(oldData, newData) { }
_setNativeClipToBounds() {
this.nativeViewProtected.clipsToBounds = true;
}
[orientationProperty.setNative](value) {
if (value === 'horizontal') {
this.mLayout.scrollDirection = 1 /* UICollectionViewScrollDirection.Horizontal */;
}
else {
this.mLayout.scrollDirection = 0 /* UICollectionViewScrollDirection.Vertical */;
}
}
eachChildView(callback) {
this.mMap.forEach((view, key) => callback(view));
}
eachChild(callback) {
this.mMap.forEach((view, key) => callback(view));
}
_updateScrollPosition() {
const view = this.nativeViewProtected;
if (!view) {
return;
}
const size = this.orientation === 'vertical' ? view.contentSize.height : view.contentSize.width;
if (size === 0) {
return;
}
this.scrollToIndexAnimated(this.selectedIndex, false);
}
[selectedIndexProperty.setNative](value, animated = true) {
if (this.isLoaded) {
this.scrollToIndexAnimated(value, animated && !this.disableAnimation);
}
}
[itemTemplatesProperty.getDefault]() {
return null;
}
[itemTemplatesProperty.setNative](value) {
this._itemTemplatesInternal = new Array(this._defaultTemplate);
if (value) {
for (let i = 0, length = value.length; i < length; i++) {
this.nativeViewProtected.registerClassForCellWithReuseIdentifier(PagerCell.class(), value[i].key);
}
this._itemTemplatesInternal = this._itemTemplatesInternal.concat(value);
}
}
[itemsProperty.setNative](value) {
if (this.indicator && value && value.length) {
this.indicator.setCount(value.length);
}
this.setObservableArrayInstance(value);
if (!value) {
this.mIsInit = false;
}
}
[autoPlayProperty.setNative](value) {
this._initAutoPlay(value);
}
[autoplayDelayProperty.setNative](value) {
if (this._autoPlayInterval) {
clearInterval(this._autoPlayInterval);
this._autoPlayInterval = undefined;
this._initAutoPlay(this.autoPlay);
}
}
_setPadding(newPadding) {
const layout = this.nativeViewProtected;
const sectionInset = layout['contentInset'];
const padding = {
top: sectionInset.top,
right: sectionInset.right,
bottom: sectionInset.bottom,
left: sectionInset.left
};
const newValue = Object.assign(padding, newPadding);
layout['contentInset'] = newValue;
}
[paddingTopProperty.setNative](value) {
this._setPadding({ top: Utils.layout.toDeviceIndependentPixels(this.effectivePaddingTop) });
}
[paddingRightProperty.setNative](value) {
this._setPadding({ right: Utils.layout.toDeviceIndependentPixels(this.effectivePaddingRight) });
}
[paddingBottomProperty.setNative](value) {
this._setPadding({ bottom: Utils.layout.toDeviceIndependentPixels(this.effectivePaddingBottom) });
}
[paddingLeftProperty.setNative](value) {
this._setPadding({ left: Utils.layout.toDeviceIndependentPixels(this.effectivePaddingLeft) });
}
_onItemsChanged(oldValue, newValue) { }
scrollToIndexAnimated(index, animate) {
if (!this.nativeViewProtected)
return;
const contentSize = this.nativeViewProtected.contentSize;
const size = this.orientation === 'vertical' ? contentSize.height : contentSize.width;
if (size === 0) {
return;
}
if (this._childrenCount === 0) {
return;
}
const maxMinIndex = Math.min(Math.max(0, index), this._childrenCount - 1);
let isNativeValueChanged = false;
if (!this.isLoaded) {
isNativeValueChanged = true;
}
else {
const page = this.page;
const frame = page && page.frame;
if (frame) {
if (frame._executingContext) {
isNativeValueChanged = frame._executingContext.entry.resolvedPage !== page;
}
else {
isNativeValueChanged = frame.currentPage !== page;
}
}
}
if (isNativeValueChanged) {
return selectedIndexProperty.nativeValueChange(this, maxMinIndex);
}
// dispatch_async(main_queue, () => {
if (this.mDataSource.collectionViewNumberOfItemsInSection(this.nativeViewProtected, 0) > maxMinIndex) {
// when we have custom layouts (they don't occupy 100% of the parent) and we use custom transformers we need to call setContentOffsetAnimated to take size into account.
// Reference: https://stackoverflow.com/a/53798708/6015400
this.nativeViewProtected.setContentOffsetAnimated(CGPointMake(1, 0), !!animate);
this.nativeViewProtected.scrollToItemAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(this.getIndex(maxMinIndex), 0), this.orientation === 'vertical' ? 2 /* UICollectionViewScrollPosition.CenteredVertically */ : 16 /* UICollectionViewScrollPosition.CenteredHorizontally */, !!animate);
}
selectedIndexProperty.nativeValueChange(this, maxMinIndex);
// });
}
refresh(delayUpdateScrollPosition = false) {
if (!this.isLoaded || !this.nativeView) {
this._isDataDirty = true;
return;
}
this._isDataDirty = false;
this.mLastLayoutKey = this._effectiveItemWidth + '_' + this._effectiveItemHeight;
// clear bindingContext when it is not observable because otherwise bindings to items won't reevaluate
this.mMap.forEach((view, nativeView, map) => {
if (!(view.bindingContext instanceof Observable)) {
view.bindingContext = null;
}
});
// TODO: this is ugly look here: https://github.com/nativescript-vue/nativescript-vue/issues/525
// this.clearRealizedCells();
// dispatch_async(main_queue, () => {
this.nativeViewProtected.reloadData();
this.nativeViewProtected.collectionViewLayout.invalidateLayout();
if (delayUpdateScrollPosition) {
setTimeout(() => {
this._updateScrollPosition();
}, 0);
}
else {
this._updateScrollPosition();
}
this._initAutoPlay(this.autoPlay);
// });
if (this.indicator) {
this.indicator.setCount(this._childrenCount);
}
}
refreshVisibleItems() {
const view = this.nativeViewProtected;
if (!view) {
return;
}
const visibles = view.indexPathsForVisibleItems;
UIView.performWithoutAnimation(() => {
view.performBatchUpdatesCompletion(() => {
view.reloadItemsAtIndexPaths(visibles);
}, null);
});
}
onLoaded() {
super.onLoaded();
if (this._isDataDirty && this._effectiveItemWidth !== undefined && this._effectiveItemHeight !== undefined) {
this.refresh();
}
this.nativeViewProtected.delegate = this.mDelegate;
if (!this.items && this._childrenCount > 0) {
selectedIndexProperty.coerce(this);
this._updateScrollPosition();
}
}
onUnloaded() {
if (this.nativeViewProtected) {
this.nativeViewProtected.delegate = null;
}
super.onUnloaded();
}
disposeNativeView() {
this.mDelegate = null;
this.mDataSource = null;
this.nativeViewProtected.delegate = null;
this.mLayout = null;
this.clearRealizedCells();
super.disposeNativeView();
}
clearRealizedCells() {
this.mMap.forEach((value, key) => {
this._removeContainer(key);
this._clearCellViews(key);
});
this.mMap.clear();
}
_clearCellViews(cell) {
// if (cell && cell.view) {
// if (cell.view.nativeViewProtected) {
// cell.view.nativeViewProtected.removeFromSuperview();
// }
// cell.owner = undefined;
// }
const view = cell.view;
if (!view) {
return;
}
// This is to clear the StackLayout that is used to wrap ProxyViewContainer instances.
if (view.parent && !(view.parent instanceof Pager)) {
this._removeView(view.parent);
}
// No need to request layout when we are removing cells.
cell.owner = undefined;
const preparing = this.mPreparingCell;
this.mPreparingCell = true;
if (view.parent && !(view.parent instanceof Pager)) {
if (!(view.parent instanceof Pager)) {
this._removeView(view.parent);
}
else {
view.parent._removeView(view);
}
}
this.mPreparingCell = preparing;
this.mMap.delete(cell);
}
[disableSwipeProperty.setNative](value) {
this.nativeViewProtected.scrollEnabled = !value;
this.mDisableSwipe = value;
}
[contentInsetAdjustmentBehaviorProperty.setNative](value) {
this.nativeViewProtected.contentInsetAdjustmentBehavior = value;
}
get disableAnimation() {
return this.mDisableAnimation;
}
set disableAnimation(value) {
this.mDisableAnimation = value;
}
_removeContainer(cell, index) {
const view = cell.view;
this.notify({
eventName: Pager.itemDisposingEvent,
index,
ios: cell,
view
});
if (view && view.parent) {
// This is to clear the StackLayout that is used to wrap ProxyViewContainer instances.
if (!(view.parent instanceof Pager)) {
this._removeView(view.parent);
}
view.parent._removeView(view);
}
this.mMap.delete(cell);
}
// called by N when the size actually changed
// _onSizeChanged() {
// dispatch_async(main_queue, () => {
// if (!this.pager) {
// return;
// }
// this.pager.reloadData();
// // if (changed) {
// this._updateScrollPosition();
// // }
// this._initAutoPlay(this.autoPlay);
// });
// }
onMeasure(widthMeasureSpec, heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.mMap.forEach((childView, pagerCell) => {
View.measureChild(this, childView, childView._currentWidthMeasureSpec, childView._currentHeightMeasureSpec);
});
}
onLayout(left, top, right, bottom) {
super.onLayout(left, top, right, bottom);
if (this.iosOverflowSafeArea) {
const safeArea = this.getSafeAreaInsets();
this._effectiveItemHeight += safeArea.top + safeArea.bottom;
}
if (!this.nativeView) {
return;
}
// this.nativeViewProtected.frame = this.nativeView.bounds;
const layoutView = this.nativeViewProtected.collectionViewLayout;
if (!layoutView) {
return;
}
layoutView.invalidateLayout();
const size = this._getSize();
const width = Utils.layout.toDevicePixels(size.width);
const height = Utils.layout.toDevicePixels(size.height);
this.mMap.forEach((childView, pagerCell) => {
View.layoutChild(this, childView, 0, 0, width, height);
});
// there is no need to call refresh if it was triggered before with same size.
// this refresh is just to handle size change
const layoutKey = this._effectiveItemWidth + '_' + this._effectiveItemHeight;
if (this.mLastLayoutKey !== layoutKey) {
this.refresh(true);
}
}
requestLayout() {
// When preparing cell don't call super - no need to invalidate our measure when cell desiredSize is changed.
if (!this.mPreparingCell) {
super.requestLayout();
}
}
_prepareCell(cell, indexPath) {
try {
this.mPreparingCell = true;
const index = indexPath.row;
let view = cell.view;
const template = this._getItemTemplate(indexPath.row);
if (!view) {
view = template.createView();
if (!view && this._itemViewLoader !== undefined) {
view = this._itemViewLoader(this._getItemTemplateKey(indexPath.row));
}
}
const bindingContext = this._getDataItem(indexPath.row);
const args = {
eventName: Pager.itemLoadingEvent,
object: this,
index,
android: undefined,
ios: cell,
view,
bindingContext
};
this.notify(args);
view = args.view || this._getDefaultItemContent(indexPath.row);
// Proxy containers should not get treated as layouts.
// Wrap them in a real layout as well.
if (view instanceof ProxyViewContainer) {
const sp = new StackLayout();
sp.addChild(view);
view = sp;
}
// If cell is reused it have old content - remove it first.
if (!cell.view) {
cell.owner = new WeakRef(view);
}
else if (cell.view !== view) {
this.mMap.delete(cell);
this._removeContainer(cell, index);
cell.view.nativeViewProtected.removeFromSuperview();
cell.owner = new WeakRef(view);
}
if (view) {
view.bindingContext = bindingContext;
}
this.mMap.set(cell, view);
if (view && !view.parent) {
this._addView(view);
// prevent infinit request layout
// view['performLayout'] = () => {
// this._layoutCell(view, indexPath);
// const size = this._getSize();
// const width = layout.toDevicePixels(size.width);
// const height = layout.toDevicePixels(size.height);
// if (view && view.isLayoutRequired) {
// View.layoutChild(this, view, 0, 0, width, height);
// }
// };
if (this.iosOverflowSafeArea) {
const innerView = UICellView.new();
innerView.view = new WeakRef(view);
innerView.addSubview(view.nativeViewProtected);
cell.contentView.addSubview(innerView);
}
else {
cell.contentView.addSubview(view.nativeViewProtected);
}
}
this._layoutCell(view, indexPath);
}
finally {
this.mPreparingCell = false;
}
}
_layoutCell(cellView, index) {
if (cellView) {
const size = this._getSize();
const width = Utils.layout.toDevicePixels(size.width);
const height = Utils.layout.toDevicePixels(size.height);
const widthMeasureSpec = Utils.layout.makeMeasureSpec(width, Utils.layout.EXACTLY);
const heightMeasureSpec = Utils.layout.makeMeasureSpec(height, Utils.layout.EXACTLY);
const measured = View.measureChild(this, cellView, widthMeasureSpec, heightMeasureSpec);
}
}
get horizontalOffset() {
return this.nativeViewProtected ? this.nativeViewProtected.contentOffset.x : 0;
}
get verticalOffset() {
return this.nativeViewProtected ? this.nativeViewProtected.contentOffset.y : 0;
}
_getSpacing() {
return Utils.layout.toDeviceIndependentPixels(this.convertToSize(this.spacing));
}
_getPeaking() {
return Utils.layout.toDeviceIndependentPixels(this.convertToSize(this.peaking));
}
_getSize() {
let width = Utils.layout.toDeviceIndependentPixels(this._effectiveItemWidth);
let height = Utils.layout.toDeviceIndependentPixels(this._effectiveItemHeight);
if (this.orientation === 'vertical') {
height = (height - (this._getSpacing() * 2 + this._getPeaking() * 2)) / this.perPage;
}
else {
width = (width - (this._getSpacing() * 2 + this._getPeaking() * 2)) / this.perPage;
}
if (Number.isNaN(width)) {
width = 0;
}
if (Number.isNaN(height)) {
height = 0;
}
return { width, height };
}
}
__decorate([
profile
], Pager.prototype, "refresh", null);
var PagerCell = /** @class */ (function (_super) {
__extends(PagerCell, _super);
function PagerCell() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(PagerCell.prototype, "view", {
get: function () {
return this.owner ? this.owner.get() : null;
},
enumerable: true,
configurable: true
});
PagerCell.initWithEmptyBackground = function () {
var cell = PagerCell.new();
// Clear background by default - this will make cells transparent
cell.backgroundColor = null;
return cell;
};
PagerCell.prototype.willMoveToSuperview = function (newSuperview) {
var parent = (this.view ? this.view.parent : null);
// When inside Pager and there is no newSuperview this cell is
// removed from native visual tree so we remove it from our tree too.
if (parent && !newSuperview) {
parent._removeContainer(this, this.index);
}
};
return PagerCell;
}(UICollectionViewCell));
var UICollectionDelegateImpl = /** @class */ (function (_super) {
__extends(UICollectionDelegateImpl, _super);
function UICollectionDelegateImpl() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.isScrolling = false;
return _this;
}
UICollectionDelegateImpl_1 = UICollectionDelegateImpl;
UICollectionDelegateImpl.initWithOwner = function (owner) {
var delegate = UICollectionDelegateImpl_1.alloc().init();
delegate._owner = owner;
return delegate;
};
UICollectionDelegateImpl.prototype.collectionViewLayoutInsetForSectionAtIndex = function (collectionView, collectionViewLayout, section) {
var owner = this._owner ? this._owner.get() : null;
if (owner) {
var inset = owner._getSpacing() + owner._getPeaking();
if (owner.orientation === 'vertical') {
return new UIEdgeInsets({
bottom: inset,
left: 0,
right: 0,
top: inset
});
}
return new UIEdgeInsets({
bottom: 0,
left: inset,
right: inset,
top: 0
});
}
return new UIEdgeInsets({ bottom: 0, left: 0, right: 0, top: 0 });
};
UICollectionDelegateImpl.prototype.collectionViewLayoutSizeForItemAtIndexPath = function (collectionView, collectionViewLayout, indexPath) {
var owner = this._owner && this._owner.get();
if (!owner)
return CGSizeZero;
var size = owner._getSize();
return CGSizeMake(size.width, size.height);
};
UICollectionDelegateImpl.prototype.collectionViewWillDisplayCellForItemAtIndexPath = function (collectionView, cell, indexPath) {
var owner = this._owner && this._owner.get();
if (owner) {
if (!owner.mIsInit) {
owner._updateScrollPosition();
collectionView.collectionViewLayout.invalidateLayout();
owner.mIsInit = true;
}
if (owner.items && indexPath.row === owner.lastIndex - owner.loadMoreCount) {
owner.notify({
eventName: Pager.loadMoreItemsEvent,
object: owner
});
}
}
if (cell.preservesSuperviewLayoutMargins) {
cell.preservesSuperviewLayoutMargins = false;
}
if (cell.layoutMargins) {
cell.layoutMargins = UIEdgeInsetsZero;
}
};
UICollectionDelegateImpl.prototype.collectionViewLayoutMinimumLineSpacingForSectionAtIndex = function (collectionView, collectionViewLayout, section) {
var _a;
var owner = this._owner ? this._owner.get() : null;
return (_a = owner === null || owner === void 0 ? void 0 : owner._getSpacing()) !== null && _a !== void 0 ? _a : 0;
};
UICollectionDelegateImpl.prototype.scrollViewWillBeginDragging = function (scrollView) {
var owner = this._owner && this._owner.get();
if (owner) {
if (owner.lastEvent === 0) {
owner.notify({
eventName: Pager.swipeStartEvent,
object: owner
});
owner.lastEvent = 1;
}
}
};
UICollectionDelegateImpl.prototype.scrollViewDidEndScrollingAnimation = function (scrollView) {
var owner = this._owner ? this._owner.get() : null;
if (owner) {
owner.notify({
eventName: Pager.swipeEvent,
object: owner
});
}
};
UICollectionDelegateImpl.prototype.scrollViewDidScroll = function (scrollView) {
var owner = this._owner.get();
if (owner) {
var width = void 0;
var offset = void 0;
var size = owner._getRealWidthHeight();
var total = void 0;
if (owner.orientation === 'vertical') {
width = size.height;
offset = scrollView.contentOffset.y;
total = scrollView.contentSize.height - scrollView.bounds.size.height;
}
else {
width = size.width;
offset = scrollView.contentOffset.x;
total = scrollView.contentSize.width - scrollView.bounds.size.width;
}
var percent = offset / total;
var progress = percent * (owner.itemCount - 1);
// if (owner.indicatorView && owner.indicatorView.setWithProgressAnimated && !Number.isNaN(progress)) {
// owner.indicatorView.progress = progress;
// }
var index = parseInt(progress.toFixed(0), 10);
if (owner.indicator && !Number.isNaN(index)) {
if (!(owner.circularMode && (index === 0 || index === owner.firstDummy))) {
owner.indicator.setSelection(owner.getPosition(index));
}
}
owner.notify({
object: owner,
eventName: Pager.scrollEvent,
selectedIndex: Math.floor(progress),
currentPosition: progress,
scrollX: owner.horizontalOffset,
scrollY: owner.verticalOffset
});
if (owner.lastEvent === 1) {
owner.notify({
eventName: Pager.swipeOverEvent,
object: owner
});
owner.lastEvent = 1;
}
// (scrollView as any).scrollToItemAtIndexPathAtScrollPositionAnimated(
// NSIndexPath.indexPathForRowInSection(Math.round(width),0), UICollectionViewScrollPosition.CenteredHorizontally, true
// );
if (owner.circularMode) {
if (!this.isScrolling) {
this.isScrolling = true;
var contentOffset = scrollView.contentOffset;
var contentSize = scrollView.contentSize;
var frameSize = scrollView.frame.size;
if (contentOffset.x <= 0) {
scrollView.contentOffset = CGPointMake(contentSize.width - frameSize.width * 2 + 2 * owner._getPeaking(), 0);
if (owner.indicator) {
owner.indicator.setSelection(owner.lastIndex, false);
}
}
else if (contentOffset.x + frameSize.width >= contentSize.width) {
scrollView.contentOffset = CGPointMake(frameSize.width - 2 * owner._getPeaking(), 0);
if (owner.indicator) {
owner.indicator.setSelection(0, false);
}
}
this.isScrolling = false;
}
}
/* if (!Number.isNaN(width)) {
let page = Math.ceil(width);
const doScroll = () => {
if (!Number.isNaN(width)) {
// scrollView.setContentOffsetAnimated(point, false);
scrollView.contentOffset = CGPointMake(Math.ceil(w) * page, scrollView.contentOffset.y);
}
};
if (page === 0) {
page = owner.itemCount - 2;
doScroll();
// selectedIndexProperty.nativeValueChange(owner, owner.itemCount - 3);
} else if (page === owner.itemCount) {
page = 1;
doScroll();
// selectedIndexProperty.nativeValueChange(owner, 0);
} else {
if (page === owner._childrenCount + 1) {
// selectedIndexProperty.nativeValueChange(owner, 0);
} else {
// selectedIndexProperty.nativeValueChange(owner, page - 1);
}
}
} */
/* if(owner){
let width = 0;
let w = (layout.toDeviceIndependentPixels(owner._effectiveItemWidth) - (((owner.perPage * 2) * owner._getSpacing()) + (owner._getPeaking() * 2))) / owner.perPage;
let h = (layout.toDeviceIndependentPixels(owner._effectiveItemHeight) - (((owner.perPage * 2) * owner._getSpacing()) + (owner._getPeaking() * 2))) / owner.perPage;
width = scrollView.contentOffset.x / w;
if (!Number.isNaN(width)) {
let page = Math.ceil(width);
const doScroll = () => {
if (!Number.isNaN(width)) {
const point = CGPointMake(Math.ceil(w) * page, scrollView.contentOffset.y);
scrollView.setContentOffsetAnimated(point, false);
}
};
if (page === 0) {
page = owner.itemCount - 2;
doScroll();
selectedIndexProperty.nativeValueChange(owner, owner.itemCount - 3);
} else if (page === owner.itemCount -1) {
page = 1;
doScroll();
selectedIndexProperty.nativeValueChange(owner, 0);
} else {
if(page === owner.itemCount + 1){
selectedIndexProperty.nativeValueChange(owner, 0);
}else {
selectedIndexProperty.nativeValueChange(owner, page - 1);
}
}
}
} */
// scrollView.setContentOffsetAnimated(CGPointMake((w * width) + 1, 0),false);
// (owner.nativeView as UICollectionView).setContentOffsetAnimated(CGPointMake((w * width) + 1, 0),false);
}
};
UICollectionDelegateImpl.prototype.scrollViewDidEndDraggingWillDecelerate = function (scrollView, decelerate) { };
UICollectionDelegateImpl.prototype.scrollViewWillEndDraggingWithVelocityTargetContentOffset = function (scrollView, velocity, targetContentOffset) {
var owner = this._owner ? this._owner.get() : null;
if (!owner)
return;
if (owner.lastEvent === 1) {
owner.notify({
eventName: Pager.swipeEndEvent,
object: owner
});
owner.lastEvent = 0;
}
};
var UICollectionDelegateImpl_1;
UICollectionDelegateImpl = UICollectionDelegateImpl_1 = __decorate([
ObjCClass(UICollectionViewDelegate, UICollectionViewDelegateFlowLayout)
], UICollectionDelegateImpl);
return UICollectionDelegateImpl;
}(NSObject));
var UICollectionViewDataSourceImpl = /** @class */ (function (_super) {
__extends(UICollectionViewDataSourceImpl, _super);
function UICollectionViewDataSourceImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
UICollectionViewDataSourceImpl_1 = UICollectionViewDataSourceImpl;
UICollectionViewDataSourceImpl.initWithOwner = function (owner) {
var delegate = UICollectionViewDataSourceImpl_1.alloc().init();
delegate._owner = owner;
return delegate;
};
UICollectionViewDataSourceImpl.prototype.collectionViewCellForItemAtIndexPath = function (collectionView, indexPath) {
var owner = this._owner ? this._owner.get() : null;
var cell;
var count = 0;
if (owner) {
count = owner._childrenCount;
if (owner.circularMode) {
count = owner.itemCount;
switch (indexPath.row) {
case 0:
indexPath = NSIndexPath.indexPathForRowInSection(owner.lastDummy, 0);
break;
case owner.firstDummy:
indexPath = NSIndexPath.indexPathForRowInSection(0, 0);
break;
default:
indexPath = NSIndexPath.indexPathForRowInSection(indexPath.row - 1, 0);
break;
}
}
}
if (owner && !owner.items && count > 0) {
var index = indexPath.row;
var data = owner._childrenViews[index];
var viewType = data.type;
owner.mPreparingCell = true;
collectionView.registerClassForCellWithReuseIdentifier(PagerCell.class(), "static-".concat(viewType));
cell = collectionView.dequeueReusableCellWithReuseIdentifierForIndexPath("static-".concat(viewType), indexPath) || PagerCell.initWithEmptyBackground();
cell.index = index;
var view = data.view;
// if (view instanceof ProxyViewContainer) {
// let sp = new StackLayout();
// sp.addChild(view);
// view = sp;
// }
// If cell is reused it has old content - remove it first.
var firstRender_1 = !cell.view;
if (!cell.view) {
cell.owner = new WeakRef(view);
}
else if (cell.view !== view) {
owner._removeView(view);
// (cell.view.nativeViewProtected as UIView).removeFromSuperview();
cell.owner = new WeakRef(view);
}
if (view && !view.parent) {
// view['performLayout'] = () => {
// View.measureChild(
// owner,
// view,
// view._currentWidthMeasureSpec,
// view._currentHeightMeasureSpec
// );
// if (view && view.isLayoutRequired) {
// View.layoutChild(owner, view, 0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
// }
// };
owner._addView(view);
// if (owner.iosOverflowSafeArea) {
var innerView = UICellView.new();
innerView.view = new WeakRef(view);
innerView.addSubview(view.nativeViewProtected);
cell.contentView.addSubview(innerView);
owner.mMap.set(cell, view);
// } else {
// cell.contentView.addSubview(view.nativeViewProtected);
// }
}
if (firstRender_1) {
view['iosIgnoreSafeArea'] = true;
}
owner._layoutCell(view, indexPath);
var size = owner._getSize();
var width = Utils.layout.toDevicePixels(size.width);
var height = Utils.layout.toDevicePixels(size.height);
if (view && view.isLayoutRequired) {
View.layoutChild(owner, view, 0, 0, width, height);
}
owner.mPreparingCell = false;
return cell;
}
var template = owner && owner._getItemTemplate(indexPath.row);
cell = collectionView.dequeueReusableCellWithReuseIdentifierForIndexPath(template.key, indexPath) || PagerCell.initWithEmptyBackground();
cell.index = indexPath;
var firstRender = !cell.view;
if (owner) {
var size = owner._getSize();
owner._prepareCell(cell, indexPath);
var cellView = cell.view;
if (firstRender) {
cellView['iosIgnoreSafeArea'] = true;
}
if (cellView && cellView.isLayoutRequired) {
View.layoutChild(owner, cellView, 0, 0, Utils.layout.toDevicePixels(size.width), Utils.layout.toDevicePixels(size.height));
}
}
return cell;
};
UICollectionViewDataSourceImpl.prototype.collectionViewNumberOfItemsInSection = function (collectionView, section) {
var owner = this._owner ? this._owner.get() : null;
// make sure we dont start to load static view if the pager is not loaded.
// otherwise static items wont "load"
if (!owner || !owner.isLoaded)
return 0;
return owner.circularMode ? owner.itemCount : owner._childrenCount;
};
UICollectionViewDataSourceImpl.prototype.numberOfSectionsInCollectionView = function (collectionView) {
return 1;
};
var UICollectionViewDataSourceImpl_1;
UICollectionViewDataSourceImpl = UICollectionViewDataSourceImpl_1 = __decorate([
ObjCClass(UICollectionViewDataSource)
], UICollectionViewDataSourceImpl);
return UICollectionViewDataSourceImpl;
}(NSObject));
var UICollectionViewFlowLinearLayoutImpl = /** @class */ (function (_super) {
__extends(UICollectionViewFlowLinearLayoutImpl, _super);
function UICollectionViewFlowLinearLayoutImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
UICollectionViewFlowLinearLayoutImpl.initWithOwner = function (owner) {
var layout = UICollectionViewFlowLinearLayoutImpl.new();
layout._owner = owner;
layout._curl = CATransition.animation();
return layout;
};
UICollectionViewFlowLinearLayoutImpl.prototype.layoutAttributesForElementsInRect = function (rect) {
var owner = this._owner ? this._owner.get() : null;
var originalLayoutAttribute = _super.prototype.layoutAttributesForElementsInRect.call(this, rect);
var visibleLayoutAttributes = NSMutableArray.alloc().init();
if (owner === null || owner === void 0 ? void 0 : owner.transformers) {
var transformsArray = owner.transformers
.split(' ')
.map(function (s) { return Pager.mRegisteredTransformers[s]; })
.filter(function (s) { return !!s; });
if (transformsArray.length) {
var collectionView = this.collectionView;
var count = originalLayoutAttribute.count;
for (var i = 0; i < count; i++) {
var attributes = originalLayoutAttribute.objectAtIndex(i);
visibleLayoutAttributes.addObject(attributes);
for (var _i = 0, transformsArray_1 = transformsArray; _i < transformsArray_1.length; _i++) {
var transformer = transformsArray_1[_i];
transformer(i, attributes, owner, collectionView);
}
}
}
return visibleLayoutAttributes;
}
return originalLayoutAttribute;
};
UICollectionViewFlowLinearLayoutImpl.prototype.shouldInvalidateLayoutForBoundsChange = function (newBounds) {
return true;
};
UICollectionViewFlowLinearLayoutImpl.prototype.initialLayoutAttributesForAppearingItemAtIndexPath = function (itemIndexPath) {
var attrs = _super.prototype.initialLayoutAttributesForAppearingItemAtIndexPath.call(this, itemIndexPath);
attrs.alpha = 1;
return attrs;
};
UICollectionViewFlowLinearLayoutImpl.prototype.finalLayoutAttributesForDisappearingItemAtIndexPath = function (itemIndexPath) {
var attrs = _super.prototype.finalLayoutAttributesForDisappearingItemAtIndexPath.call(this, itemIndexPath);
attrs.alpha = 1;
return attrs;
};
UICollectionViewFlowLinearLayoutImpl.prototype.targetCon