UNPKG

nativescript-ui-sidedrawer

Version:

Add additional space to your app. Use it for navigation or custom content. Slides in from all four sides of the screen.

409 lines 17.9 kB
export * from './common'; import * as commonModule from './common'; import { View, Utils, IOSHelper } from '@nativescript/core'; //////////////////////////////////////////////// export class RadSideDrawer extends commonModule.RadSideDrawer { constructor() { super(); let screen = UIScreen.mainScreen; this._ios = TKSideDrawerView.alloc().initWithFrame(screen.bounds); this._nativeDelegate = TKSideDrawerDelegateImpl.initWithOwner(this); this._ios.defaultSideDrawer.width = this.drawerContentSize; this._ios.defaultSideDrawer.style.blurType = 0; this._ios.defaultSideDrawer.headerView = null; this._ios.defaultSideDrawer.footerView = null; this._ios.defaultSideDrawer.delegate = this._nativeDelegate; this.setShadowColor(this.shadowColor); } // @ts-ignore get ios() { return this._ios; } createNativeView() { if (!this._isRootView) { this.page.on('navigatingFrom', this.onNavigatingFrom, this); } return this.ios; } disposeNativeView() { if (!this._isRootView) { this.page.off('navigatingFrom', this.onNavigatingFrom, this); } } onNavigatingFrom(args) { if (this.getIsOpen()) { this.closeDrawer(); } } bringMainContentOnTop() { this._ios.defaultSideDrawer.superview.bringSubviewToFront(this._ios.defaultSideDrawer); this.viewController.view.bringSubviewToFront(this._ios.hostview); } reattachGestures() { if (!this.mainContent && !this.mainContent.viewController && !this.mainContent.viewController.view && !this.mainContent.viewController.view.superview && !this.mainContent.viewController.view.superview.superview) { console.log('Error: No `this.mainContent` found. Cannot attach gestures to RadSideDrawer.'); return; } // We need to reattach the gestures since we have manipulated the native view hierarchy in `_addViewToNativeVisualTree` this._ios.defaultSideDrawer.detachGesturesFromView(this.nativeViewProtected); this._ios.defaultSideDrawer.attachGesturesToView(this.mainContent.viewController.view.superview.superview); } isRootDrawer() { return this.viewController && this.viewController.view; } onUnloaded() { super.onUnloaded(); } // data changed event handlers _onDrawerLocationChanged(oldValue, newValue) { if (!newValue) { return; } this.setDrawerLocation(newValue); } _onShadowColorChanged(oldValue, newValue) { this.setShadowColor(newValue); } setShadowColor(color) { this._ios.defaultSideDrawer.style.shadowMode = 2; this._ios.defaultSideDrawer.style.dimOpacity = 0.42; this._ios.defaultSideDrawer.style.shadowRadius = 0; this._ios.defaultSideDrawer.style.shadowOpacity = 1; // 0-1, higher is darker this._ios.defaultSideDrawer.style.shadowColor = color ? color.ios : RadSideDrawer.shadowColorProperty.defaultValue.ios; } _onGesturesEnabledChanged(oldValue, newValue) { let value = newValue; this.ios.defaultSideDrawer.allowGestures = value; } _onAllowEdgeSwipeChanged(oldValue, newValue) { let value = newValue; this.ios.defaultSideDrawer.allowEdgeSwipe = value; } setDrawerLocation(newLocation) { switch (newLocation) { case commonModule.SideDrawerLocation.Left: this._ios.defaultSideDrawer.position = 0 /* TKSideDrawerPosition.Left */; break; case commonModule.SideDrawerLocation.Right: this._ios.defaultSideDrawer.position = 1 /* TKSideDrawerPosition.Right */; break; case commonModule.SideDrawerLocation.Top: this._ios.defaultSideDrawer.position = 2 /* TKSideDrawerPosition.Top */; break; case commonModule.SideDrawerLocation.Bottom: this._ios.defaultSideDrawer.position = 3 /* TKSideDrawerPosition.Bottom */; break; } this.requestLayout(); } _onDrawerContentSizeChanged(oldValue, newValue) { let value = newValue; this._ios.defaultSideDrawer.width = value; } _onDrawerTransitionChanged(oldValue, newValue) { let value = newValue; let finalVal; if (typeof value === 'string') { switch (value.toLowerCase()) { case commonModule.FadeTransitionString: { finalVal = new FadeTransition(); break; } case commonModule.PushTransitionString: { finalVal = new PushTransition(); break; } case commonModule.RevealTransitionString: { finalVal = new RevealTransition(); break; } case commonModule.ReverseSlideOutTransitionString: { finalVal = new ReverseSlideOutTransition(); break; } case commonModule.ScaleDownPusherTransitionString: { finalVal = new ScaleDownPusherTransition(); break; } case commonModule.ScaleUpTransitionString: { finalVal = new ScaleUpTransition(); break; } case commonModule.SlideAlongTransitionString: { finalVal = new SlideAlongTransition(); break; } case commonModule.SlideInOnTopTransitionString: { finalVal = new SlideInOnTopTransition(); break; } default: { console.log('Error: Not supported value (' + value + ") set to 'drawerTransition'"); finalVal = new SlideInOnTopTransition(); break; } } if (this.drawerTransition !== finalVal) { this.drawerTransition = finalVal; return; } } else { finalVal = value; } this._ios.defaultSideDrawer.transition = finalVal.getNativeContent(); } get _nativeView() { return this._ios; } closeDrawer() { if (this._ios) { this._ios.defaultSideDrawer.dismiss(); super.closeDrawer(); } } showDrawer() { if (this._ios) { this._ios.defaultSideDrawer.show(); super.showDrawer(); } } eachChildView(callback) { const mainContent = this.mainContent; if (mainContent) { callback(mainContent); } if (this.drawerContent) { callback(this.drawerContent); } } onLayout(left, top, right, bottom) { // In the case where the RadSideDrawer is not root view of the app // it doesn't have a viewController and childViewControllers. In this case // the RadSideDrawer must lay out its children drawerContent and mainContent if (!this.viewController) { // need setTimeout to allow the children get correct safeAreaInsets setTimeout(() => { let width = right - left; let height = bottom - top; let screenWidth = width; let screenHeight = height; let screen = UIScreen.mainScreen; let drawerSize = Utils.layout.toDevicePixels(this.drawerContentSize); let insets = this.getSafeAreaInsets(); let pos = this._ios.defaultSideDrawer.position; switch (pos) { case 2 /* TKSideDrawerPosition.Top */: this.drawerContent.layout(0, 0, right, drawerSize + insets.top); break; case 3 /* TKSideDrawerPosition.Bottom */: this.drawerContent.layout(0, bottom - drawerSize - insets.bottom, right, bottom); break; case 0 /* TKSideDrawerPosition.Left */: this.drawerContent.layout(0, 0, drawerSize + insets.left, bottom); break; case 1 /* TKSideDrawerPosition.Right */: this.drawerContent.layout(0, 0, drawerSize + insets.right, bottom); break; } this.mainContent.layout(0, 0, width, height); }); } else { // TODO: Investigate if this cannot be resolved in tns-core-modules UILayoutViewController, if it can remove this code // We need to move the `mainContent` and `drawerContent native view to the root UIViewController in order for the safe areas to be updated when 'in-call' status bar is toggled. // We also need to move the gesture handlers to the new views. // Related to issue https://github.com/NativeScript/nativescript-ui-feedback/issues/1189 if (this.areViewsRearranged) { this.areViewsRearranged = false; this.bringMainContentOnTop(); this.reattachGestures(); } } } onMeasure(widthMeasureSpec, heightMeasureSpec) { let pos = this._ios.defaultSideDrawer.position; let drawerWidth = widthMeasureSpec; let drawerHeight = heightMeasureSpec; // need to manually handle the safe inset if it's not root side drawer let drawerSize = Utils.layout.toDevicePixels(this.drawerContentSize); if (!this.viewController) { const insets = this.getSafeAreaInsets(); switch (pos) { case 2 /* TKSideDrawerPosition.Top */: drawerSize -= insets.top; break; case 3 /* TKSideDrawerPosition.Bottom */: drawerSize -= insets.bottom; break; case 0 /* TKSideDrawerPosition.Left */: drawerSize -= insets.left; break; case 1 /* TKSideDrawerPosition.Right */: drawerSize -= insets.right; break; } } if (pos === 2 /* TKSideDrawerPosition.Top */ || pos === 3 /* TKSideDrawerPosition.Bottom */) { View.measureChild(this, this.drawerContent, drawerWidth, Utils.layout.makeMeasureSpec(drawerSize, Utils.layout.EXACTLY)); } else { View.measureChild(this, this.drawerContent, Utils.layout.makeMeasureSpec(drawerSize, Utils.layout.EXACTLY), drawerHeight); } let result = View.measureChild(this, this.mainContent, widthMeasureSpec, heightMeasureSpec); let width = Utils.layout.getMeasureSpecSize(widthMeasureSpec); let widthMode = Utils.layout.getMeasureSpecMode(widthMeasureSpec); let height = Utils.layout.getMeasureSpecSize(heightMeasureSpec); let heightMode = Utils.layout.getMeasureSpecMode(heightMeasureSpec); let widthAndState = View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0); let heightAndState = View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0); this.setMeasuredDimension(widthAndState, heightAndState); } _addViewToNativeVisualTree(child, atIndex) { super._addViewToNativeVisualTree(child, atIndex); this.areViewsRearranged = true; const controller = this.viewController; let content = child.nativeViewProtected; if (controller && !child.viewController) { child.viewController = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(child)); const view = child.viewController.view; view.addSubview(child.nativeViewProtected); content = view; } const childController = child.viewController; if (controller && childController) { controller.addChildViewController(childController); } if (child === this.mainContent) { if (this.isRootDrawer() && childController) { // TODO: Investigate if this cannot be resolved in tns-core-modules UILayoutViewController, if it can remove this code // We need to move the `mainContent` native view to the root UIViewController in order for the safe areas to be updated when 'in-call' status bar is toggled. // Related to issue https://github.com/NativeScript/nativescript-ui-feedback/issues/1189 this._ios.setMainView(childController.view); controller.view.addSubview(this._ios.hostview); } else { this._ios.setMainView(content); } } else if (child === this.drawerContent) { this._ios.defaultSideDrawer.content = content; if (controller && childController) { // TODO: Investigate if this cannot be resolved in tns-core-modules UILayoutViewController, if it can remove this code // We need to move the `drawerContent` native view to the root UIViewController in order for the safe areas to be updated when 'in-call' status bar is toggled. // Related to issue https://github.com/NativeScript/nativescript-ui-feedback/issues/1189 controller.view.addSubview(this._ios.defaultSideDrawer); } } return true; } } //////////////////////////////////////////////// // TRANSITIONS //////////////////////////////////////////////// export class FadeTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 6 /* TKSideDrawerTransitionType.FadeIn */; } } export class PushTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 2 /* TKSideDrawerTransitionType.Push */; } } export class RevealTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 1 /* TKSideDrawerTransitionType.Reveal */; } } export class ReverseSlideOutTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 4 /* TKSideDrawerTransitionType.ReverseSlideOut */; } } export class ScaleDownPusherTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 7 /* TKSideDrawerTransitionType.ScaleDownPusher */; } } export class ScaleUpTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 5 /* TKSideDrawerTransitionType.ScaleUp */; } } export class SlideAlongTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 3 /* TKSideDrawerTransitionType.SlideAlong */; } } export class SlideInOnTopTransition extends commonModule.DrawerTransitionBase { getNativeContent() { return 0 /* TKSideDrawerTransitionType.SlideInOnTop */; } } var TKSideDrawerDelegateImpl = /** @class */ (function (_super) { __extends(TKSideDrawerDelegateImpl, _super); function TKSideDrawerDelegateImpl() { return _super !== null && _super.apply(this, arguments) || this; } TKSideDrawerDelegateImpl.initWithOwner = function (owner) { var delegate = new TKSideDrawerDelegateImpl(); delegate._owner = new WeakRef(owner); return delegate; }; TKSideDrawerDelegateImpl.prototype.willShowSideDrawer = function (sideDrawer) { var owner = this._owner.get(); if (owner && owner.hasListeners(commonModule.RadSideDrawer.drawerOpeningEvent)) { var args = { eventName: commonModule.RadSideDrawer.drawerOpeningEvent, object: owner, returnValue: false }; owner.notify(args); } }; TKSideDrawerDelegateImpl.prototype.didShowSideDrawer = function (sideDrawer) { var owner = this._owner.get(); if (owner && owner.hasListeners(commonModule.RadSideDrawer.drawerOpenedEvent)) { var args = { eventName: commonModule.RadSideDrawer.drawerOpenedEvent, object: owner }; owner.notify(args); } }; TKSideDrawerDelegateImpl.prototype.willDismissSideDrawer = function (sideDrawer) { var owner = this._owner.get(); if (owner && owner.hasListeners(commonModule.RadSideDrawer.drawerClosingEvent)) { var args = { eventName: commonModule.RadSideDrawer.drawerClosingEvent, object: owner, returnValue: false }; owner.notify(args); } }; TKSideDrawerDelegateImpl.prototype.didDismissSideDrawer = function (sideDrawer) { var owner = this._owner.get(); if (owner && owner.hasListeners(commonModule.RadSideDrawer.drawerClosedEvent)) { var args = { eventName: commonModule.RadSideDrawer.drawerClosedEvent, object: owner }; owner.notify(args); } }; TKSideDrawerDelegateImpl.prototype.didPanSideDrawer = function (sideDrawer) { var owner = this._owner.get(); if (owner && owner.hasListeners(commonModule.RadSideDrawer.drawerPanEvent)) { var args = { eventName: commonModule.RadSideDrawer.drawerPanEvent, object: owner }; owner.notify(args); } }; TKSideDrawerDelegateImpl.ObjCProtocols = [TKSideDrawerDelegate]; return TKSideDrawerDelegateImpl; }(NSObject)); //# sourceMappingURL=index.ios.js.map