Skip to content

Commit b015eee

Browse files
authored
fix(ios): dialog handling with top view controller (#8609)
1 parent 446163d commit b015eee

5 files changed

Lines changed: 83 additions & 44 deletions

File tree

‎e2e/ui-tests-app/app/modal-view/login-page.ts‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Page, ShownModallyData } from "tns-core-modules/ui/page";
22
import { EventData, fromObject } from "tns-core-modules/data/observable";
3+
import { alert } from "tns-core-modules/ui/dialogs";
34

45
export function onShowingModally(args: ShownModallyData) {
56
console.log("login-page.onShowingModally, context: " + args.context);
@@ -12,7 +13,19 @@ export function onShowingModally(args: ShownModallyData) {
1213
onLoginButtonTap: function () {
1314
console.log("login-page.onLoginButtonTap");
1415
args.closeCallback(this.username, this.password);
15-
}
16+
},
17+
showAlert: function () {
18+
alert("showing alert!");
19+
args.closeCallback();
20+
},
21+
openNestedModal: function () {
22+
page.showModal("modal-view/nested-modal", {
23+
context: "First",
24+
closeCallback: () => {
25+
console.log("login-page.openNestedModal");
26+
}
27+
});
28+
}
1629
});
1730
}
1831

‎e2e/ui-tests-app/app/modal-view/login-page.xml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@
77
<TextField hint="username" text="{{ username }}"/>
88
<TextField hint="password" text="{{ password }}" secure="true"/>
99
<Button text="Login" tap="{{ onLoginButtonTap }}"/>
10+
<Button text="Show Alert" tap="{{ showAlert }}"/>
11+
<Button text="Open Nested Modal" tap="{{ openNestedModal }}"/>
1012
</StackLayout>
1113
</Page>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Page, ShownModallyData } from "tns-core-modules/ui/page";
2+
import { EventData, fromObject } from "tns-core-modules/data/observable";
3+
import { alert } from "tns-core-modules/ui/dialogs";
4+
5+
export function onShowingModally(args: ShownModallyData) {
6+
console.log("nested-modal.onShowingModally, context: " + args.context);
7+
const page = <Page>args.object;
8+
9+
page.bindingContext = fromObject({
10+
context: args.context,
11+
onTap: function () {
12+
alert("it works!");
13+
}
14+
});
15+
}
16+
17+
export function onShownModally(args: ShownModallyData) {
18+
console.log("nested-modal.onShownModally, context: " + args.context);
19+
}
20+
21+
export function onLoaded(args: EventData) {
22+
console.log("nested-modal.onLoaded");
23+
}
24+
25+
export function onUnloaded() {
26+
console.log("nested-modal.onUnloaded");
27+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
2+
showingModally="onShowingModally"
3+
shownModally="onShownModally"
4+
loaded="onLoaded" unloaded="onUnloaded" backgroundColor="Red">
5+
<StackLayout backgroundColor="PaleGreen" margin="10">
6+
<Label text="{{ context }}"/>
7+
<Button text="Show Alert" tap="{{ onTap }}"/>
8+
</StackLayout>
9+
</Page>

‎nativescript-core/ui/dialogs/dialogs.ios.ts‎

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/**
22
* iOS specific dialogs functions implementation.
33
*/
4-
import { ios as iosView } from "../core/view";
4+
import { ios as iosView, traceCategories, traceWrite, traceMessageType } from "../core/view";
55
import { ConfirmOptions, PromptOptions, PromptResult, LoginOptions, LoginResult, ActionOptions } from ".";
66
import { getCurrentPage, getLabelColor, getButtonColors, getTextFieldColor, isDialogOptions, inputType, capitalizationType, ALERT, OK, CONFIRM, CANCEL, PROMPT, parseLoginOptions } from "./dialogs-common";
77
import { isString, isDefined, isFunction } from "../../utils/types";
8-
import { getRootView } from "../../application";
8+
import { getRootView, ios } from "../../application";
99

1010
export * from "./dialogs-common";
1111

@@ -200,54 +200,42 @@ export function login(...args: any[]): Promise<LoginResult> {
200200
}
201201

202202
function showUIAlertController(alertController: UIAlertController) {
203-
let currentView = getCurrentPage() || getRootView();
203+
let viewController = ios.rootController;
204+
205+
while (viewController && viewController.presentedViewController) {
206+
viewController = viewController.presentedViewController;
207+
}
204208

205-
if (currentView) {
206-
currentView = currentView.modal || currentView;
209+
if (!viewController) {
210+
traceWrite(`No root controller found to open dialog.`, traceCategories.Error, traceMessageType.warn);
211+
212+
return;
213+
}
207214

208-
//get to the top most view controller on the stack
209-
while (currentView && currentView.modal) {
210-
currentView = currentView.modal;
211-
}
212-
213-
let viewController: UIViewController = currentView.ios;
215+
if (alertController.popoverPresentationController) {
216+
alertController.popoverPresentationController.sourceView = viewController.view;
217+
alertController.popoverPresentationController.sourceRect = CGRectMake(viewController.view.bounds.size.width / 2.0, viewController.view.bounds.size.height / 2.0, 1.0, 1.0);
218+
alertController.popoverPresentationController.permittedArrowDirections = 0;
219+
}
214220

215-
if (viewController.presentedViewController) {
216-
viewController = viewController.presentedViewController;
217-
}
221+
let color = getButtonColors().color;
222+
if (color) {
223+
alertController.view.tintColor = color.ios;
224+
}
218225

219-
if (!(currentView.ios instanceof UIViewController)) {
220-
const parentWithController = iosView.getParentWithViewController(currentView);
221-
viewController = parentWithController ? parentWithController.viewController : undefined;
226+
let lblColor = getLabelColor();
227+
if (lblColor) {
228+
if (alertController.title) {
229+
let title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
230+
alertController.setValueForKey(title, "attributedTitle");
222231
}
223-
224-
if (viewController) {
225-
if (alertController.popoverPresentationController) {
226-
alertController.popoverPresentationController.sourceView = viewController.view;
227-
alertController.popoverPresentationController.sourceRect = CGRectMake(viewController.view.bounds.size.width / 2.0, viewController.view.bounds.size.height / 2.0, 1.0, 1.0);
228-
alertController.popoverPresentationController.permittedArrowDirections = 0;
229-
}
230-
231-
let color = getButtonColors().color;
232-
if (color) {
233-
alertController.view.tintColor = color.ios;
234-
}
235-
236-
let lblColor = getLabelColor();
237-
if (lblColor) {
238-
if (alertController.title) {
239-
let title = NSAttributedString.alloc().initWithStringAttributes(alertController.title, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
240-
alertController.setValueForKey(title, "attributedTitle");
241-
}
242-
if (alertController.message) {
243-
let message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
244-
alertController.setValueForKey(message, "attributedMessage");
245-
}
246-
}
247-
248-
viewController.presentModalViewControllerAnimated(alertController, true);
232+
if (alertController.message) {
233+
let message = NSAttributedString.alloc().initWithStringAttributes(alertController.message, <any>{ [NSForegroundColorAttributeName]: lblColor.ios });
234+
alertController.setValueForKey(message, "attributedMessage");
249235
}
250236
}
237+
238+
viewController.presentModalViewControllerAnimated(alertController, true);
251239
}
252240

253241
export function action(): Promise<string> {

0 commit comments

Comments
 (0)