mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 19:26:42 +08:00
fix(ios): dialog handling with top view controller (#8609)
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
import { Page, ShownModallyData } from "tns-core-modules/ui/page";
|
import { Page, ShownModallyData } from "tns-core-modules/ui/page";
|
||||||
import { EventData, fromObject } from "tns-core-modules/data/observable";
|
import { EventData, fromObject } from "tns-core-modules/data/observable";
|
||||||
|
import { alert } from "tns-core-modules/ui/dialogs";
|
||||||
|
|
||||||
export function onShowingModally(args: ShownModallyData) {
|
export function onShowingModally(args: ShownModallyData) {
|
||||||
console.log("login-page.onShowingModally, context: " + args.context);
|
console.log("login-page.onShowingModally, context: " + args.context);
|
||||||
@ -12,7 +13,19 @@ export function onShowingModally(args: ShownModallyData) {
|
|||||||
onLoginButtonTap: function () {
|
onLoginButtonTap: function () {
|
||||||
console.log("login-page.onLoginButtonTap");
|
console.log("login-page.onLoginButtonTap");
|
||||||
args.closeCallback(this.username, this.password);
|
args.closeCallback(this.username, this.password);
|
||||||
}
|
},
|
||||||
|
showAlert: function () {
|
||||||
|
alert("showing alert!");
|
||||||
|
args.closeCallback();
|
||||||
|
},
|
||||||
|
openNestedModal: function () {
|
||||||
|
page.showModal("modal-view/nested-modal", {
|
||||||
|
context: "First",
|
||||||
|
closeCallback: () => {
|
||||||
|
console.log("login-page.openNestedModal");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,5 +7,7 @@
|
|||||||
<TextField hint="username" text="{{ username }}"/>
|
<TextField hint="username" text="{{ username }}"/>
|
||||||
<TextField hint="password" text="{{ password }}" secure="true"/>
|
<TextField hint="password" text="{{ password }}" secure="true"/>
|
||||||
<Button text="Login" tap="{{ onLoginButtonTap }}"/>
|
<Button text="Login" tap="{{ onLoginButtonTap }}"/>
|
||||||
|
<Button text="Show Alert" tap="{{ showAlert }}"/>
|
||||||
|
<Button text="Open Nested Modal" tap="{{ openNestedModal }}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
|
27
e2e/ui-tests-app/app/modal-view/nested-modal.ts
Normal file
27
e2e/ui-tests-app/app/modal-view/nested-modal.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Page, ShownModallyData } from "tns-core-modules/ui/page";
|
||||||
|
import { EventData, fromObject } from "tns-core-modules/data/observable";
|
||||||
|
import { alert } from "tns-core-modules/ui/dialogs";
|
||||||
|
|
||||||
|
export function onShowingModally(args: ShownModallyData) {
|
||||||
|
console.log("nested-modal.onShowingModally, context: " + args.context);
|
||||||
|
const page = <Page>args.object;
|
||||||
|
|
||||||
|
page.bindingContext = fromObject({
|
||||||
|
context: args.context,
|
||||||
|
onTap: function () {
|
||||||
|
alert("it works!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onShownModally(args: ShownModallyData) {
|
||||||
|
console.log("nested-modal.onShownModally, context: " + args.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onLoaded(args: EventData) {
|
||||||
|
console.log("nested-modal.onLoaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onUnloaded() {
|
||||||
|
console.log("nested-modal.onUnloaded");
|
||||||
|
}
|
9
e2e/ui-tests-app/app/modal-view/nested-modal.xml
Normal file
9
e2e/ui-tests-app/app/modal-view/nested-modal.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
|
||||||
|
showingModally="onShowingModally"
|
||||||
|
shownModally="onShownModally"
|
||||||
|
loaded="onLoaded" unloaded="onUnloaded" backgroundColor="Red">
|
||||||
|
<StackLayout backgroundColor="PaleGreen" margin="10">
|
||||||
|
<Label text="{{ context }}"/>
|
||||||
|
<Button text="Show Alert" tap="{{ onTap }}"/>
|
||||||
|
</StackLayout>
|
||||||
|
</Page>
|
@ -1,11 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* iOS specific dialogs functions implementation.
|
* iOS specific dialogs functions implementation.
|
||||||
*/
|
*/
|
||||||
import { ios as iosView } from "../core/view";
|
import { ios as iosView, traceCategories, traceWrite, traceMessageType } from "../core/view";
|
||||||
import { ConfirmOptions, PromptOptions, PromptResult, LoginOptions, LoginResult, ActionOptions } from ".";
|
import { ConfirmOptions, PromptOptions, PromptResult, LoginOptions, LoginResult, ActionOptions } from ".";
|
||||||
import { getCurrentPage, getLabelColor, getButtonColors, getTextFieldColor, isDialogOptions, inputType, capitalizationType, ALERT, OK, CONFIRM, CANCEL, PROMPT, parseLoginOptions } from "./dialogs-common";
|
import { getCurrentPage, getLabelColor, getButtonColors, getTextFieldColor, isDialogOptions, inputType, capitalizationType, ALERT, OK, CONFIRM, CANCEL, PROMPT, parseLoginOptions } from "./dialogs-common";
|
||||||
import { isString, isDefined, isFunction } from "../../utils/types";
|
import { isString, isDefined, isFunction } from "../../utils/types";
|
||||||
import { getRootView } from "../../application";
|
import { getRootView, ios } from "../../application";
|
||||||
|
|
||||||
export * from "./dialogs-common";
|
export * from "./dialogs-common";
|
||||||
|
|
||||||
@ -200,54 +200,42 @@ export function login(...args: any[]): Promise<LoginResult> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showUIAlertController(alertController: UIAlertController) {
|
function showUIAlertController(alertController: UIAlertController) {
|
||||||
let currentView = getCurrentPage() || getRootView();
|
let viewController = ios.rootController;
|
||||||
|
|
||||||
|
while (viewController && viewController.presentedViewController) {
|
||||||
|
viewController = viewController.presentedViewController;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentView) {
|
if (!viewController) {
|
||||||
currentView = currentView.modal || currentView;
|
traceWrite(`No root controller found to open dialog.`, traceCategories.Error, traceMessageType.warn);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//get to the top most view controller on the stack
|
if (alertController.popoverPresentationController) {
|
||||||
while (currentView && currentView.modal) {
|
alertController.popoverPresentationController.sourceView = viewController.view;
|
||||||
currentView = currentView.modal;
|
alertController.popoverPresentationController.sourceRect = CGRectMake(viewController.view.bounds.size.width / 2.0, viewController.view.bounds.size.height / 2.0, 1.0, 1.0);
|
||||||
|
alertController.popoverPresentationController.permittedArrowDirections = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let color = getButtonColors().color;
|
||||||
|
if (color) {
|
||||||
|
alertController.view.tintColor = color.ios;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lblColor = getLabelColor();
|
||||||
|
if (lblColor) {
|
||||||
|
if (alertController.title) {
|
||||||
|
let title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||||
|
alertController.setValueForKey(title, "attributedTitle");
|
||||||
}
|
}
|
||||||
|
if (alertController.message) {
|
||||||
let viewController: UIViewController = currentView.ios;
|
let message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
||||||
|
alertController.setValueForKey(message, "attributedMessage");
|
||||||
if (viewController.presentedViewController) {
|
|
||||||
viewController = viewController.presentedViewController;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(currentView.ios instanceof UIViewController)) {
|
|
||||||
const parentWithController = iosView.getParentWithViewController(currentView);
|
|
||||||
viewController = parentWithController ? parentWithController.viewController : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewController) {
|
|
||||||
if (alertController.popoverPresentationController) {
|
|
||||||
alertController.popoverPresentationController.sourceView = viewController.view;
|
|
||||||
alertController.popoverPresentationController.sourceRect = CGRectMake(viewController.view.bounds.size.width / 2.0, viewController.view.bounds.size.height / 2.0, 1.0, 1.0);
|
|
||||||
alertController.popoverPresentationController.permittedArrowDirections = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let color = getButtonColors().color;
|
|
||||||
if (color) {
|
|
||||||
alertController.view.tintColor = color.ios;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lblColor = getLabelColor();
|
|
||||||
if (lblColor) {
|
|
||||||
if (alertController.title) {
|
|
||||||
let title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
|
||||||
alertController.setValueForKey(title, "attributedTitle");
|
|
||||||
}
|
|
||||||
if (alertController.message) {
|
|
||||||
let message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
|
|
||||||
alertController.setValueForKey(message, "attributedMessage");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewController.presentModalViewControllerAnimated(alertController, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewController.presentModalViewControllerAnimated(alertController, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function action(): Promise<string> {
|
export function action(): Promise<string> {
|
||||||
|
Reference in New Issue
Block a user