feat(view): added iOS parameter for modal presentation style (#6409)

* feat(view): added iOS parameter for modal presentation style

* Now passing options to showModal in one argument

* refactor: Move context and close in modal options

* chore: Comments added for UIModalPresentationStyle.Popover case

* refactor: Use modalOptions in e2e demo

* chore: fix pbroken test
This commit is contained in:
Nicu
2018-12-13 17:03:25 +02:00
committed by Alexander Vakrilov
parent 44dba1a0b7
commit 540b2b4f82
6 changed files with 264 additions and 108 deletions

View File

@@ -1,46 +1,61 @@
import { Page } from "tns-core-modules/ui/page";
import { Label } from "tns-core-modules/ui/label";
function createCloseCallback(label: Label, context?: string): (username: string, password: string) => void {
return function (username: string, password: string) {
let result = username + "/" + password;
result = context ? context + "/" + result : result;
console.log(result);
label.text = result;
}
}
function openModal(page: Page, label: Label, context: string) {
page.showModal("ui-tests-app/modal-view/login-page", {
context,
closeCallback: createCloseCallback(label, context),
fullscreen: false,
});
}
export function onTap(args) {
const page = <Page>args.object.page;
const label = page.getViewById<Label>("label");
var fullscreen = (<any>args.object).text.indexOf("(full-screen)") !== -1;
page.showModal("ui-tests-app/modal-view/login-page", "context", function (username: string, password: string) {
console.log(username + "/" + password);
label.text = username + "/" + password;
}, fullscreen);
page.showModal("ui-tests-app/modal-view/login-page", {
context: "context",
closeCallback: createCloseCallback(label),
fullscreen
});
}
export function onTapStretched(args) {
const page = <Page>args.object.page;
const label = page.getViewById<Label>("label");
var fullscreen = false;
var stretched = true;
page.showModal("ui-tests-app/modal-view/login-page", "context", function (username: string, password: string) {
console.log(username + "/" + password);
label.text = username + "/" + password;
}, fullscreen, false, stretched);
}
function openModal(page: Page, label: Label, context: string) {
page.showModal("ui-tests-app/modal-view/login-page", context, function (username: string, password: string) {
const result = context + "/" + username + "/" + password;
console.log(result);
label.text = result;
}, false);
page.showModal("ui-tests-app/modal-view/login-page", {
context: "context",
closeCallback: createCloseCallback(label),
fullscreen: false,
animated: false,
stretched: true
});
}
export function onTapSecondModalInCB(args) {
const page = <Page>args.object.page;
const label = page.getViewById<Label>("label");
page.showModal("ui-tests-app/modal-view/login-page", "First", function (username: string, password: string) {
const result = "First/" + username + "/" + password;
console.log(result);
label.text = result;
page.showModal("ui-tests-app/modal-view/login-page", {
context: "First",
closeCallback: (username: string, password: string) => {
const result = "First/" + username + "/" + password;
console.log(result);
label.text = result;
// Open second modal in the close callback of the first one.
openModal(page, label, "Second");
// Open second modal in the close callback of the first one.
openModal(page, label, "Second");
}
});
}

View File

@@ -1,4 +1,4 @@
// >> article-require-page-module
// >> article-require-page-module
import { Page, ShownModallyData, NavigatedData } from "tns-core-modules/ui/page";
// FrameModule is needed in order to have an option to navigate to the new page.
import { topmost, NavigationEntry } from "tns-core-modules/ui/frame";
@@ -422,8 +422,7 @@ export function test_WhenPageIsNavigatedToFrameCurrentPageIsNowTheSameAsThePage(
}
export function test_WhenInnerViewCallsCloseModal_WithArguments_ShouldPassResult() {
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) =>
{
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) => {
const page = <Page>args.object;
const button = <Button>page.content;
return button.closeModal.bind(button);
@@ -431,8 +430,7 @@ export function test_WhenInnerViewCallsCloseModal_WithArguments_ShouldPassResult
}
export function test_WhenInnerViewCallsCloseModal_WithoutArguments_ShouldWork() {
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) =>
{
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) => {
const page = <Page>args.object;
const button = <Button>page.content;
return button.closeModal.bind(button);
@@ -440,15 +438,13 @@ export function test_WhenInnerViewCallsCloseModal_WithoutArguments_ShouldWork()
}
export function test_WhenInnerViewCallsCloseCallback_WithArguments_ShouldPassResult() {
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) =>
{
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) => {
return args.closeCallback;
}, "return value");
}
export function test_WhenInnerViewCallsCloseCallback_WithoutArguments_ShouldWork() {
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) =>
{
_test_WhenInnerViewCallsCloseModal((args: ShownModallyData) => {
return args.closeCallback;
});
}
@@ -460,14 +456,14 @@ function _test_WhenInnerViewCallsCloseModal(closeModalGetter: (ShownModallyData)
modalClosedWithResult = returnValue === result;
}
const modalPageShownModallyEventHandler = function(args: ShownModallyData) {
const modalPageShownModallyEventHandler = function (args: ShownModallyData) {
const page = <Page>args.object;
page.off(View.shownModallyEvent, modalPageShownModallyEventHandler);
closeModalGetter(args)(result);
}
const hostNavigatedToEventHandler = function(args: NavigatedData) {
const hostNavigatedToEventHandler = function (args: NavigatedData) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -482,11 +478,11 @@ function _test_WhenInnerViewCallsCloseModal(closeModalGetter: (ShownModallyData)
(<Button>page.content).showModal(modalPage, {}, modalCloseCallback);
}
const masterPageFactory = function(): Page {
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenInnerViewCallsCloseModal_WithArguments_ShouldPassResult";
masterPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler)
const button = new Button();
button.text = "TAP";
masterPage.content = button;
@@ -511,7 +507,7 @@ export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal()
modalClosed = true;
}
const createTabItems = function(count: number) {
const createTabItems = function (count: number) {
var items = new Array<TabViewItem>();
for (var i = 0; i < count; i++) {
@@ -527,13 +523,13 @@ export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal()
return items;
}
const modalPageShownModallyEventHandler = function(args: ShownModallyData) {
const modalPageShownModallyEventHandler = function (args: ShownModallyData) {
const page = <Page>args.object;
page.off(View.shownModallyEvent, modalPageShownModallyEventHandler);
args.closeCallback();
}
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -544,11 +540,11 @@ export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal()
tabViewItem.showModal(modalPage, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function(): Page {
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal";
masterPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler)
const tabView = new TabView();
tabView.items = createTabItems(2);
masterPage.content = tabView;
@@ -566,11 +562,14 @@ export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal()
}
}
export function test_WhenViewBaseCallsShowModal_WithoutArguments_ShouldThrow() {
let navigatedTo = false;
let modalThrows = false;
export function test_WhenViewBaseCallsShowModal_WithShowModalOptionsArguments_ShouldOpenModal() {
let modalClosed = false;
const createTabItems = function(count: number) {
const modalCloseCallback = function (returnValue: any) {
modalClosed = true;
}
const createTabItems = function (count: number) {
var items = new Array<TabViewItem>();
for (var i = 0; i < count; i++) {
@@ -586,10 +585,69 @@ export function test_WhenViewBaseCallsShowModal_WithoutArguments_ShouldThrow() {
return items;
}
const hostNavigatedToEventHandler = function(args) {
const modalPageShownModallyEventHandler = function (args: ShownModallyData) {
const page = <Page>args.object;
page.off(View.shownModallyEvent, modalPageShownModallyEventHandler);
args.closeCallback();
}
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
const modalPage = new Page();
modalPage.id = "modalPage_test_WhenViewBaseCallsShowModal_WithShowModalOptionsArguments_ShouldOpenModal";
modalPage.on(View.shownModallyEvent, modalPageShownModallyEventHandler);
const tabViewItem = (<TabView>page.content).items[0];
tabViewItem.showModal(modalPage, {
context: {},
closeCallback: modalCloseCallback,
fullscreen: false,
animated: false
});
}
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenViewBaseCallsShowModal_WithShowModalOptionsArguments_ShouldOpenModal";
masterPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler)
const tabView = new TabView();
tabView.items = createTabItems(2);
masterPage.content = tabView;
return masterPage;
};
helper.navigate(masterPageFactory);
TKUnit.waitUntilReady(() => modalClosed);
}
export function test_WhenViewBaseCallsShowModal_WithoutArguments_ShouldThrow() {
let navigatedTo = false;
let modalThrows = false;
const createTabItems = function (count: number) {
var items = new Array<TabViewItem>();
for (var i = 0; i < count; i++) {
var label = new Label();
label.text = "Tab " + i;
var tabEntry = new TabViewItem();
tabEntry.title = "Tab " + i;
tabEntry.view = label;
items.push(tabEntry);
}
return items;
}
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
const hostPage = <Page>args.object;
const tabViewItem = (<TabView>page.content).items[0];
try {
@@ -601,11 +659,11 @@ export function test_WhenViewBaseCallsShowModal_WithoutArguments_ShouldThrow() {
navigatedTo = true;
}
const masterPageFactory = function(): Page {
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenViewBaseCallsShowModal_WithoutArguments_ShouldThrow";
masterPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler)
const tabView = new TabView();
tabView.items = createTabItems(2);
masterPage.content = tabView;
@@ -667,7 +725,7 @@ export function test_WhenRootTabViewShownModallyItCanCloseModal() {
modalClosed = true;
}
const createTabItems = function(count: number) {
const createTabItems = function (count: number) {
var items = new Array<TabViewItem>();
for (var i = 0; i < count; i++) {
@@ -683,11 +741,11 @@ export function test_WhenRootTabViewShownModallyItCanCloseModal() {
return items;
}
const tabViewShownModallyEventHandler = function(args: ShownModallyData) {
const tabViewShownModallyEventHandler = function (args: ShownModallyData) {
args.closeCallback("return value");
}
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -698,7 +756,7 @@ export function test_WhenRootTabViewShownModallyItCanCloseModal() {
page.showModal(tabView, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function(): Page {
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenRootTabViewShownModallyItCanCloseModal";
masterPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -832,11 +890,11 @@ export function test_WhenModalPageShownHostPageNavigationEventsShouldNotBeRaised
hostNavigatedFromCount++;
};
const modalPageShownModallyEventHandler = function() {
const modalPageShownModallyEventHandler = function () {
TKUnit.assertEqual(stack().length, 1, "Single frame should be instantiated at this point!");
}
const hostNavigatedToEventHandler2 = function(args: NavigatedData) {
const hostNavigatedToEventHandler2 = function (args: NavigatedData) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler2);
@@ -852,7 +910,7 @@ export function test_WhenModalPageShownHostPageNavigationEventsShouldNotBeRaised
page.showModal(modalPage, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenModalPageShownHostPageNavigationEventsShouldNotBeRaised";
@@ -915,12 +973,12 @@ export function test_WhenModalPageShownModalNavigationToEventsShouldBeRaised() {
modalNavigatedFromCount++;
};
const modalFrameShownModallyEventHandler = function(args) {
const modalFrameShownModallyEventHandler = function (args) {
const basePath = "ui/page/";
const entry: NavigationEntry = {
moduleName: basePath + "modal-page"
};
};
const modalPage = createViewFromEntry(entry) as Page;
modalPage.on(Page.navigatingToEvent, modalNavigatingToEventHandler);
modalPage.on(Page.navigatedToEvent, modalNavigatedToEventHandler);
@@ -932,7 +990,7 @@ export function test_WhenModalPageShownModalNavigationToEventsShouldBeRaised() {
let modalFrame;
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -941,7 +999,7 @@ export function test_WhenModalPageShownModalNavigationToEventsShouldBeRaised() {
page.showModal(modalFrame, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenModalPageShownModalNavigationToEventsShouldBeRaised";
@@ -981,11 +1039,11 @@ export function test_WhenModalFrameShownModalEventsRaisedOnRootModalFrame() {
ready = true;
}
const modalFrameShowingModallyEventHandler = function(args: ShownModallyData) {
const modalFrameShowingModallyEventHandler = function (args: ShownModallyData) {
showingModallyCount++;
}
const modalFrameShownModallyEventHandler = function(args: ShownModallyData) {
const modalFrameShownModallyEventHandler = function (args: ShownModallyData) {
shownModallyCount++;
TKUnit.assertEqual(stack().length, 2, "Host and modal frame should be instantiated at this point!");
@@ -994,7 +1052,7 @@ export function test_WhenModalFrameShownModalEventsRaisedOnRootModalFrame() {
let modalFrame;
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -1016,7 +1074,7 @@ export function test_WhenModalFrameShownModalEventsRaisedOnRootModalFrame() {
page.showModal(modalFrame, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenModalFrameShownModalEventsRaisedOnRootModalFrame";
@@ -1051,11 +1109,11 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalPage() {
ready = true;
}
const modalPageShowingModallyEventHandler = function(args: ShownModallyData) {
const modalPageShowingModallyEventHandler = function (args: ShownModallyData) {
showingModallyCount++;
}
const modalPageShownModallyEventHandler = function(args: ShownModallyData) {
const modalPageShownModallyEventHandler = function (args: ShownModallyData) {
shownModallyCount++;
setTimeout(() => {
@@ -1063,7 +1121,7 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalPage() {
}, 0);
}
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -1078,7 +1136,7 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalPage() {
page.showModal(modalPage, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function (): Page {
const masterPage = new Page();
masterPage.id = "masterPage_test_WhenModalPageShownShowModalEventsRaisedOnRootModalPage";
@@ -1114,15 +1172,15 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalTabView()
setTimeout(() => ready = true, 50);
}
const modalTabViewShowingModallyEventHandler = function(args: ShownModallyData) {
const modalTabViewShowingModallyEventHandler = function (args: ShownModallyData) {
showingModallyCount++;
}
const modalTabViewShownModallyEventHandler = function(args: ShownModallyData) {
const modalTabViewShownModallyEventHandler = function (args: ShownModallyData) {
shownModallyCount++;
}
const hostNavigatedToEventHandler = function(args) {
const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);
@@ -1139,7 +1197,7 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalTabView()
TKUnit.assertEqual(stack().length, 2, "Host and tab modal frame should be instantiated at this point!");
page.showModal(modalTabView, { }, modalCloseCallback, false, false);
page.showModal(modalTabView, {}, modalCloseCallback, false, false);
}
const masterPageFactory = function (): Page {

View File

@@ -46,6 +46,43 @@ export function isEventOrGesture(name: string, view: ViewBase): boolean;
*/
export function getViewById(view: ViewBase, id: string): ViewBase;
export interface ShowModalOptions {
/**
* Any context you want to pass to the modally shown view. This same context will be available in the arguments of the shownModally event handler.
*/
context: any;
/**
* A function that will be called when the view is closed. Any arguments provided when calling ShownModallyData.closeCallback will be available here.
*/
closeCallback: Function;
/**
* An optional parameter specifying whether to show the modal view in full-screen mode.
*/
fullscreen?: boolean;
/**
* An optional parameter specifying whether to show the modal view with animation.
*/
animated?: boolean;
/**
* An optional parameter specifying whether to stretch the modal view when not in full-screen mode.
*/
stretched?: boolean;
/**
* An optional parameter that specify options specific to iOS as an object.
*/
ios?: {
/**
* The UIModalPresentationStyle to be used when showing the dialog in iOS .
*/
presentationStyle: any /* UIModalPresentationStyle */
}
}
export abstract class ViewBase extends Observable {
// Dynamic properties.
left: Length;
@@ -110,6 +147,7 @@ export abstract class ViewBase extends Observable {
//@endprivate
/**
* @deprecated Use showModal with ShowModalOptions instead.
* Shows the View contained in moduleName as a modal view.
* @param moduleName - The name of the module to load starting from the application root.
* @param context - Any context you want to pass to the modally shown view.
@@ -123,6 +161,7 @@ export abstract class ViewBase extends Observable {
showModal(moduleName: string, context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean): ViewBase;
/**
* @deprecated Use showModal with ShowModalOptions instead.
* Shows the view passed as parameter as a modal view.
* @param view - View instance to be shown modally.
* @param context - Any context you want to pass to the modally shown view. This same context will be available in the arguments of the shownModally event handler.
@@ -133,6 +172,20 @@ export abstract class ViewBase extends Observable {
*/
showModal(view: ViewBase, context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean): ViewBase;
/**
* Shows the View contained in moduleName as a modal view.
* @param moduleName - The name of the module to load starting from the application root.
* @param modalOptions - A ShowModalOptions instance
*/
showModal(moduleName: string, modalOptions: ShowModalOptions): ViewBase;
/**
* Shows the view passed as parameter as a modal view.
* @param view - View instance to be shown modally.
* @param modalOptions - A ShowModalOptions instance
*/
showModal(view: ViewBase, modalOptions: ShowModalOptions): ViewBase;
/**
* Deprecated. Showing view as modal is deprecated.
* Use showModal method with arguments.
@@ -259,7 +312,7 @@ export abstract class ViewBase extends Observable {
public requestLayout(): void;
/**
* Iterates over children of type ViewBase.
* Iterates over children of type ViewBase.
* @param callback Called for each child of type ViewBase. Iteration stops if this method returns falsy value.
*/
public eachChild(callback: (child: ViewBase) => boolean): void;
@@ -291,7 +344,7 @@ export abstract class ViewBase extends Observable {
/**
* @private
* Notifies each child's css state for change, recursively.
* Either the style scope, className or id properties were changed.
* Either the style scope, className or id properties were changed.
*/
_onCssStateChange(): void;
@@ -309,7 +362,7 @@ export abstract class ViewBase extends Observable {
_context: any /* android.content.Context */;
/**
/**
* Setups the UI for ViewBase and all its children recursively.
* This method should *not* be overridden by derived views.
*/

View File

@@ -7,7 +7,8 @@ import {
import {
ViewBase, Property, booleanConverter, EventData, layout,
getEventOrGestureName, traceEnabled, traceWrite, traceCategories,
InheritedProperty
InheritedProperty,
ShowModalOptions
} from "../view-base";
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
@@ -215,25 +216,41 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
return undefined;
}
public showModal(): ViewDefinition {
if (arguments.length === 0) {
private getModalOptions(args: IArguments): { view: ViewCommon, options: ShowModalOptions } {
if (args.length === 0) {
throw new Error("showModal without parameters is deprecated. Please call showModal on a view instance instead.");
} else {
const firstAgrument = arguments[0];
const context: any = arguments[1];
const closeCallback: Function = arguments[2];
const fullscreen: boolean = arguments[3];
const animated = arguments[4];
const stretched = arguments[5];
let options: ShowModalOptions = null;
const view = firstAgrument instanceof ViewCommon
? firstAgrument : <ViewCommon>createViewFromEntry({ moduleName: firstAgrument });
if (args.length === 2) {
options = <ShowModalOptions>args[1];
} else {
// TODO: Add deprecation warning
options = {
context: args[1],
closeCallback: args[2],
fullscreen: args[3],
animated: args[4],
stretched: args[5]
};
}
view._showNativeModalView(this, context, closeCallback, fullscreen, animated, stretched);
return view;
const firstArgument = args[0];
const view = firstArgument instanceof ViewCommon
? firstArgument : <ViewCommon>createViewFromEntry({ moduleName: firstArgument });
return { view, options };
}
}
public showModal(): ViewDefinition {
const { view, options } = this.getModalOptions(arguments);
view._showNativeModalView(this, options);
return view;
}
public closeModal(...args) {
let closeCallback = this._closeModalCallback;
if (closeCallback) {
@@ -250,12 +267,12 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
return this._modal;
}
protected _showNativeModalView(parent: ViewCommon, context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean) {
protected _showNativeModalView(parent: ViewCommon, options: ShowModalOptions) { //context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean, iosOpts?: any) {
_rootModalViews.push(this);
parent._modal = this;
this._modalParent = parent;
this._modalContext = context;
this._modalContext = options.context;
const that = this;
this._closeModalCallback = function (...originalArgs) {
if (that._closeModalCallback) {
@@ -268,8 +285,8 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
parent._modal = null;
const whenClosedCallback = () => {
if (typeof closeCallback === "function") {
closeCallback.apply(undefined, originalArgs);
if (typeof options.closeCallback === "function") {
options.closeCallback.apply(undefined, originalArgs);
}
}

View File

@@ -6,7 +6,7 @@ import {
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
traceEnabled, traceWrite, traceCategories, traceNotifyEvent,
paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty,
Color, EventData
Color, EventData, ShowModalOptions
} from "./view-common";
import {
@@ -574,9 +574,8 @@ export class View extends ViewCommon {
return result | (childMeasuredState & layout.MEASURED_STATE_MASK);
}
protected _showNativeModalView(parent: View, context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean) {
super._showNativeModalView(parent, context, closeCallback, fullscreen, stretched);
protected _showNativeModalView(parent: View, options: ShowModalOptions) { //context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean, iosOpts?: any) {
super._showNativeModalView(parent, options);
if (!this.backgroundColor) {
this.backgroundColor = new Color("White");
}
@@ -590,8 +589,8 @@ export class View extends ViewCommon {
const dialogOptions: DialogOptions = {
owner: this,
fullscreen: !!fullscreen,
stretched: !!stretched,
fullscreen: !!options.fullscreen,
stretched: !!options.stretched,
shownCallback: () => this._raiseShownModallyEvent(),
dismissCallback: () => this.closeModal()
}

View File

@@ -5,7 +5,7 @@ import { booleanConverter, Property } from "../view";
import {
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
traceEnabled, traceWrite, traceCategories, traceError, traceMessageType, getAncestor
traceEnabled, traceWrite, traceCategories, traceError, traceMessageType, ShowModalOptions
} from "./view-common";
import { ios as iosBackground, Background } from "../../styling/background";
@@ -150,7 +150,7 @@ export class View extends ViewCommon {
}
public onLayout(left: number, top: number, right: number, bottom: number): void {
//
//
}
public _setNativeViewFrame(nativeView: UIView, frame: CGRect): void {
@@ -371,7 +371,7 @@ export class View extends ViewCommon {
return this._suspendCATransaction || this._suspendNativeUpdatesCount;
}
protected _showNativeModalView(parent: View, context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean) {
protected _showNativeModalView(parent: View, options: ShowModalOptions) { //context: any, closeCallback: Function, fullscreen?: boolean, animated?: boolean, stretched?: boolean, iosOpts?: any) {
const parentWithController = ios.getParentWithViewController(parent);
if (!parentWithController) {
traceWrite(`Could not find parent with viewController for ${parent} while showing modal view.`,
@@ -394,7 +394,7 @@ export class View extends ViewCommon {
this._setupAsRootView({});
super._showNativeModalView(parentWithController, context, closeCallback, fullscreen, stretched);
super._showNativeModalView(parentWithController, options);
let controller = this.viewController;
if (!controller) {
const nativeView = this.ios || this.nativeViewProtected;
@@ -407,17 +407,31 @@ export class View extends ViewCommon {
this.viewController = controller;
}
if (fullscreen) {
if (options.fullscreen) {
controller.modalPresentationStyle = UIModalPresentationStyle.FullScreen;
} else {
controller.modalPresentationStyle = UIModalPresentationStyle.FormSheet;
}
if (options.ios && options.ios.presentationStyle) {
const presentationStyle = options.ios.presentationStyle;
controller.modalPresentationStyle = presentationStyle;
if (presentationStyle === UIModalPresentationStyle.Popover) {
const popoverPresentationController = controller.popoverPresentationController;
const view = parent.nativeViewProtected;
// Note: sourceView and sourceRect are needed to specify the anchor location for the popover.
// Note: sourceView should be the button triggering the modal. If it the Page the popover might appear "behind" the page content
popoverPresentationController.sourceView = view;
popoverPresentationController.sourceRect = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height);
}
}
this.horizontalAlignment = "stretch";
this.verticalAlignment = "stretch";
this._raiseShowingModallyEvent();
animated = animated === undefined ? true : !!animated;
const animated = options.animated === undefined ? true : !!options.animated;
(<any>controller).animated = animated;
parentController.presentViewControllerAnimatedCompletion(controller, animated, null);
const transitionCoordinator = iosUtils.getter(parentController, parentController.transitionCoordinator);