mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 21:01:34 +08:00
Merge pull request #3543 from NativeScript/fix-modal-crashes
Fix: Modal crashes in Android and IOS
This commit is contained in:
@ -291,7 +291,7 @@ typedExports.start = function (entry?: NavigationEntry) {
|
|||||||
if(window) {
|
if(window) {
|
||||||
var rootController = window.rootViewController;
|
var rootController = window.rootViewController;
|
||||||
if(rootController) {
|
if(rootController) {
|
||||||
rootController.presentViewControllerAnimatedCompletion(rootView.ios.controller, utils.ios.MajorVersion >= 7, null);
|
rootController.presentViewControllerAnimatedCompletion(rootView.ios.controller, true, null);
|
||||||
uiUtils.ios._layoutRootView(rootView, utils.ios.getter(UIScreen, UIScreen.mainScreen).bounds);
|
uiUtils.ios._layoutRootView(rootView, utils.ios.getter(UIScreen, UIScreen.mainScreen).bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,20 +155,7 @@ export class View extends ViewCommon {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is done because when rotated in iOS7 there is rotation applied on the first subview on the Window which is our frame.nativeView.view.
|
|
||||||
// // If we set it it should be transformed so it is correct.
|
|
||||||
// // When in landscape in iOS 7 there is transformation on the first subview of the window so we set frame to its subview.
|
|
||||||
// // in iOS 8 we set frame to subview again otherwise we get clipped.
|
|
||||||
// let nativeView: UIView;
|
|
||||||
// if (!this.parent && this.nativeView.subviews.count > 0 && ios.MajorVersion < 8) {
|
|
||||||
// if (traceEnabled()) {
|
|
||||||
// traceWrite(this + " has no parent. Setting frame to first child instead.", traceCategories.Layout);
|
|
||||||
// }
|
|
||||||
// nativeView = (<UIView>this.nativeView.subviews[0]);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
let nativeView = this.nativeView;
|
let nativeView = this.nativeView;
|
||||||
// }
|
|
||||||
|
|
||||||
let frame = CGRectMake(left, top, right - left, bottom - top);
|
let frame = CGRectMake(left, top, right - left, bottom - top);
|
||||||
this._setNativeViewFrame(nativeView, frame);
|
this._setNativeViewFrame(nativeView, frame);
|
||||||
|
@ -8,6 +8,8 @@ import { isString, isDefined, isFunction } from "utils/types";
|
|||||||
import * as utils from "utils/utils";
|
import * as utils from "utils/utils";
|
||||||
import getter = utils.ios.getter;
|
import getter = utils.ios.getter;
|
||||||
|
|
||||||
|
export * from "./dialogs-common";
|
||||||
|
|
||||||
class UIAlertViewDelegateImpl extends NSObject implements UIAlertViewDelegate {
|
class UIAlertViewDelegateImpl extends NSObject implements UIAlertViewDelegate {
|
||||||
public static ObjCProtocols = [UIAlertViewDelegate];
|
public static ObjCProtocols = [UIAlertViewDelegate];
|
||||||
|
|
||||||
|
@ -39,7 +39,13 @@ function ensureDialogFragmentClass() {
|
|||||||
this._owner.verticalAlignment = this._fullscreen ? VerticalAlignment.STRETCH : VerticalAlignment.MIDDLE;
|
this._owner.verticalAlignment = this._fullscreen ? VerticalAlignment.STRETCH : VerticalAlignment.MIDDLE;
|
||||||
this._owner.actionBarHidden = true;
|
this._owner.actionBarHidden = true;
|
||||||
|
|
||||||
dialog.setContentView(this._owner._nativeView, this._owner._nativeView.getLayoutParams());
|
const nativeView = <android.view.View>this._owner._nativeView;
|
||||||
|
let layoutParams = nativeView.getLayoutParams();
|
||||||
|
if (!layoutParams) {
|
||||||
|
layoutParams = new org.nativescript.widgets.CommonLayoutParams();
|
||||||
|
nativeView.setLayoutParams(layoutParams);
|
||||||
|
}
|
||||||
|
dialog.setContentView(this._owner._nativeView, layoutParams);
|
||||||
|
|
||||||
const window = dialog.getWindow();
|
const window = dialog.getWindow();
|
||||||
window.setBackgroundDrawable(new android.graphics.drawable.ColorDrawable(android.graphics.Color.TRANSPARENT));
|
window.setBackgroundDrawable(new android.graphics.drawable.ColorDrawable(android.graphics.Color.TRANSPARENT));
|
||||||
|
@ -84,9 +84,12 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner._modalParent) {
|
const modalParent = owner._modalParent;
|
||||||
let isTablet = device.deviceType === "Tablet";
|
if (modalParent) {
|
||||||
let isFullScreen = !owner._UIModalPresentationFormSheet || !isTablet;
|
// if inside horizontally compact environment - fullScreen will be forced
|
||||||
|
let isFullScreen = !owner._UIModalPresentationFormSheet ||
|
||||||
|
(modalParent.nativeView.traitCollection.horizontalSizeClass === UIUserInterfaceSizeClass.Compact);
|
||||||
|
|
||||||
let frame = isFullScreen ? getter(UIScreen, UIScreen.mainScreen).bounds : this.view.frame;
|
let frame = isFullScreen ? getter(UIScreen, UIScreen.mainScreen).bounds : this.view.frame;
|
||||||
let size = frame.size;
|
let size = frame.size;
|
||||||
let width = size.width;
|
let width = size.width;
|
||||||
@ -99,12 +102,6 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
superViewRotationRadians = atan2f(transform.b, transform.a);
|
superViewRotationRadians = atan2f(transform.b, transform.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ios.MajorVersion < 8 && ios.isLandscape() && !superViewRotationRadians) {
|
|
||||||
// in iOS 7 when in landscape we switch width with height because on device they don't change even when rotated.
|
|
||||||
width = size.height;
|
|
||||||
height = size.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bottom = height;
|
let bottom = height;
|
||||||
let statusBarHeight = uiUtils.ios.getStatusBarHeight();
|
let statusBarHeight = uiUtils.ios.getStatusBarHeight();
|
||||||
let statusBarVisible = !getter(UIApplication, UIApplication.sharedApplication).statusBarHidden;
|
let statusBarVisible = !getter(UIApplication, UIApplication.sharedApplication).statusBarHidden;
|
||||||
@ -116,20 +113,9 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
let widthSpec = layout.makeMeasureSpec(width, mode);
|
let widthSpec = layout.makeMeasureSpec(width, mode);
|
||||||
let heightSpec = layout.makeMeasureSpec(height, mode);
|
let heightSpec = layout.makeMeasureSpec(height, mode);
|
||||||
|
|
||||||
View.measureChild(owner._modalParent, owner, widthSpec, heightSpec);
|
View.measureChild(modalParent, owner, widthSpec, heightSpec);
|
||||||
let top = ((backgroundSpanUnderStatusBar && isFullScreen) || ios.MajorVersion < 8 || !isFullScreen) ? 0 : statusBarHeight;
|
let top = ((backgroundSpanUnderStatusBar && isFullScreen) || !isFullScreen) ? 0 : statusBarHeight;
|
||||||
View.layoutChild(owner._modalParent, owner, 0, top, width, bottom);
|
View.layoutChild(modalParent, owner, 0, top, width, bottom);
|
||||||
|
|
||||||
if (ios.MajorVersion < 8) {
|
|
||||||
if (!backgroundSpanUnderStatusBar && (!isTablet || isFullScreen)) {
|
|
||||||
if (ios.isLandscape() && !superViewRotationRadians) {
|
|
||||||
this.view.center = CGPointMake(this.view.center.x - statusBarHeight, this.view.center.y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.view.center = CGPointMake(this.view.center.x, this.view.center.y + statusBarHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(owner + ", native frame = " + NSStringFromCGRect(this.view.frame), traceCategories.Layout);
|
traceWrite(owner + ", native frame = " + NSStringFromCGRect(this.view.frame), traceCategories.Layout);
|
||||||
@ -156,8 +142,9 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let frame = this.navigationController ? (<any>this.navigationController).owner : null;
|
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
|
||||||
let newEntry = this[ENTRY];
|
const newEntry = this[ENTRY];
|
||||||
|
const modalParent = page._modalParent;
|
||||||
|
|
||||||
// Don't raise event if currentPage was showing modal page.
|
// Don't raise event if currentPage was showing modal page.
|
||||||
if (!page._presentedViewController && newEntry && (!frame || frame.currentPage !== page)) {
|
if (!page._presentedViewController && newEntry && (!frame || frame.currentPage !== page)) {
|
||||||
@ -167,6 +154,11 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
|
|
||||||
page._enableLoadedEvents = true;
|
page._enableLoadedEvents = true;
|
||||||
|
|
||||||
|
// Add page to frame if showing modal page.
|
||||||
|
if (modalParent) {
|
||||||
|
modalParent.frame._addView(page);
|
||||||
|
}
|
||||||
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
if (!page.parent) {
|
if (!page.parent) {
|
||||||
if (!frame._currentEntry) {
|
if (!frame._currentEntry) {
|
||||||
@ -279,7 +271,7 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
public viewDidDisappear(animated: boolean): void {
|
public viewDidDisappear(animated: boolean): void {
|
||||||
super.viewDidDisappear(animated);
|
super.viewDidDisappear(animated);
|
||||||
|
|
||||||
let page = this._owner.get();
|
const page = this._owner.get();
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(page + " viewDidDisappear", traceCategories.Navigation);
|
traceWrite(page + " viewDidDisappear", traceCategories.Navigation);
|
||||||
}
|
}
|
||||||
@ -288,12 +280,13 @@ class UIViewControllerImpl extends UIViewController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modalParent = page._modalParent;
|
const modalParent = page._modalParent;
|
||||||
page._modalParent = undefined;
|
page._modalParent = undefined;
|
||||||
page._UIModalPresentationFormSheet = false;
|
page._UIModalPresentationFormSheet = false;
|
||||||
|
|
||||||
// Clear modal flag on parent page.
|
// Clear up after modal page has closed.
|
||||||
if (modalParent) {
|
if (modalParent) {
|
||||||
|
modalParent.frame._removeView(page);
|
||||||
modalParent._modal = undefined;
|
modalParent._modal = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +423,7 @@ export class Page extends PageBase {
|
|||||||
|
|
||||||
super._raiseShowingModallyEvent();
|
super._raiseShowingModallyEvent();
|
||||||
|
|
||||||
parent.ios.presentViewControllerAnimatedCompletion(this._ios, ios.MajorVersion >= 7, null);
|
parent.ios.presentViewControllerAnimatedCompletion(this._ios, true, null);
|
||||||
let transitionCoordinator = getter(parent.ios, parent.ios.transitionCoordinator);
|
let transitionCoordinator = getter(parent.ios, parent.ios.transitionCoordinator);
|
||||||
if (transitionCoordinator) {
|
if (transitionCoordinator) {
|
||||||
UIViewControllerTransitionCoordinator.prototype.animateAlongsideTransitionCompletion.call(transitionCoordinator, null, () => this._raiseShownModallyEvent());
|
UIViewControllerTransitionCoordinator.prototype.animateAlongsideTransitionCompletion.call(transitionCoordinator, null, () => this._raiseShownModallyEvent());
|
||||||
@ -445,7 +438,7 @@ export class Page extends PageBase {
|
|||||||
|
|
||||||
protected _hideNativeModalView(parent: Page) {
|
protected _hideNativeModalView(parent: Page) {
|
||||||
parent.requestLayout();
|
parent.requestLayout();
|
||||||
parent._ios.dismissModalViewControllerAnimated(ios.MajorVersion >= 7);
|
parent._ios.dismissModalViewControllerAnimated(true);
|
||||||
|
|
||||||
super._hideNativeModalView(parent);
|
super._hideNativeModalView(parent);
|
||||||
}
|
}
|
||||||
@ -520,7 +513,7 @@ export class Page extends PageBase {
|
|||||||
statusBarHeight = 0;
|
statusBarHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.frame && this.frame._getNavBarVisible(this)) {
|
if (!this._modalParent && this.frame && this.frame._getNavBarVisible(this)) {
|
||||||
// Measure ActionBar with the full height.
|
// Measure ActionBar with the full height.
|
||||||
let actionBarSize = View.measureChild(this, this.actionBar, widthMeasureSpec, heightMeasureSpec);
|
let actionBarSize = View.measureChild(this, this.actionBar, widthMeasureSpec, heightMeasureSpec);
|
||||||
actionBarWidth = actionBarSize.measuredWidth;
|
actionBarWidth = actionBarSize.measuredWidth;
|
||||||
|
Reference in New Issue
Block a user