Generated platforms declarations for iOS 11

Fixed broken unit-tests
ios layout now run only for the innermost viewcontoller
ios layout for viewcontrollers now implemented with constraints
Added ios11 safeAreas layout support
onMeasure back for frame and tab-view so that they won't throw exception if measure is called on them
Page parents layout updated after page is layout so that inner layout flags are correct
This commit is contained in:
Hristo Hristov
2017-10-06 09:57:29 +03:00
parent 38d026a3df
commit 199d83c902
18 changed files with 479 additions and 322 deletions

View File

@@ -356,11 +356,9 @@ export function waitUntilReady(isReady: () => boolean, timeoutSec: number = 3, s
}
if (Application.ios) {
// const waitTime = 1 / 10000;
const timeoutMs = timeoutSec * 1000;
let totalWaitTime = 0;
while (true) {
// const nsDate = <any>NSDate.dateWithTimeIntervalSinceNow(waitTime);
const begin = time();
const currentRunLoop = utils.ios.getter(NSRunLoop, NSRunLoop.currentRunLoop);
currentRunLoop.limitDateForMode(currentRunLoop.currentMode);

View File

@@ -15,6 +15,7 @@ exports.pageLoaded = pageLoaded;
// << article-set-bindingcontext
import * as TKUnit from "../../TKUnit";
import * as helper from "../helper";
import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
import { View, PercentLength, Observable, unsetValue, EventData, isIOS } from "tns-core-modules/ui/core/view";
import { Label } from "tns-core-modules/ui/label";
@@ -562,31 +563,40 @@ export function test_percent_width_and_height_support() {
export function test_percent_margin_support() {
const testPage = new Page();
testPage.id = "ttest_percent_margin_support";
const gridLayout = new GridLayout();
const stackLayout = new StackLayout();
stackLayout.margin = "10%";
testPage.content = stackLayout;
gridLayout.addChild(stackLayout);
testPage.content = gridLayout;
const pageWidth = testPage.getMeasuredWidth();
const pageHeight = testPage.getMeasuredHeight()
helper.navigate(() => testPage);
const marginLeft = pageWidth * 0.1;
const marginTop = pageHeight * 0.1;
const parentBounds = gridLayout._getCurrentLayoutBounds();
const parentWidth = parentBounds.right - parentBounds.left;
const parentHeight = parentBounds.bottom - parentBounds.top;
const bounds = stackLayout._getCurrentLayoutBounds();
TKUnit.assertEqual(bounds.left, Math.round(marginLeft), "Page's content LEFT position incorrect");
TKUnit.assertEqual(bounds.top, Math.round(marginTop), "Page's content TOP position incorrect");
TKUnit.assertEqual(bounds.right, Math.round(marginLeft + pageWidth), "Page's content RIGHT position incorrect");
TKUnit.assertEqual(bounds.bottom, Math.round(marginTop + pageHeight), "Page's content BOTTOM position incorrect");
const marginLeft = Math.round(parentWidth * 0.1);
const marginTop = Math.round(parentHeight * 0.1);
let bounds = stackLayout._getCurrentLayoutBounds();
TKUnit.assertEqual(Math.round(bounds.left), marginLeft, "Stack LEFT position incorrect");
TKUnit.assertEqual(Math.round(bounds.top), marginTop, "Stack TOP position incorrect");
TKUnit.assertEqual(Math.round(bounds.bottom - bounds.top), parentHeight - (2 * marginTop), "Stack HEIGHT incorrect");
TKUnit.assertEqual(Math.round(bounds.right - bounds.left), parentWidth - (2 * marginLeft), "Stack WIDTH incorrect");
TKUnit.assertEqual(Math.round(bounds.right), parentWidth - marginLeft, "Stack RIGHT position incorrect");
TKUnit.assertEqual(Math.round(bounds.bottom), parentHeight - marginTop, "Stack BOTTOM position incorrect");
//reset values.
testPage.margin = "0";
stackLayout.margin = "0";
TKUnit.waitUntilReady(() => stackLayout.isLayoutValid);
TKUnit.assertTrue(PercentLength.equals(testPage.marginLeft, 0));
TKUnit.assertTrue(PercentLength.equals(testPage.marginTop, 0));
TKUnit.assertTrue(PercentLength.equals(testPage.marginRight, 0));
TKUnit.assertTrue(PercentLength.equals(testPage.marginBottom, 0));
bounds = stackLayout._getCurrentLayoutBounds();
TKUnit.assertEqual(bounds.left, 0, "Stack LEFT position incorrect");
TKUnit.assertEqual(bounds.top, 0, "Stack TOP position incorrect");
TKUnit.assertEqual(bounds.bottom - bounds.top, parentHeight, "Stack HEIGHT incorrect");
TKUnit.assertEqual(bounds.right - bounds.left, parentWidth, "Stack WIDTH incorrect");
TKUnit.assertEqual(bounds.right, parentWidth, "Stack RIGHT position incorrect");
TKUnit.assertEqual(bounds.bottom, parentHeight, "Stack BOTTOM position incorrect");
}
//export function test_ModalPage_Layout_is_Correct() {

View File

@@ -1,5 +1,6 @@
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
import { Page, layout, View, EventData } from "tns-core-modules/ui/page";
import { ios as iosView } from "tns-core-modules/ui/core/view";
import { Label } from "tns-core-modules/ui/label";
import { topmost } from "tns-core-modules/ui/frame";
import * as uiUtils from "tns-core-modules/ui/utils";
@@ -72,6 +73,11 @@ function getHeight(view: View): number {
return bounds.bottom - bounds.top;
}
function getNativeHeight(view: View): number {
const bounds = view.nativeViewProtected.frame;
return layout.toDevicePixels(bounds.size.height);
}
export function test_correct_layout_scrollable_content_false() {
const page = new Page();
(<any>page).scrollableContent = false;
@@ -82,6 +88,7 @@ export function test_correct_layout_scrollable_content_false() {
const tabItem = new TabViewItem();
tabItem.title = "Item";
const lbl = new Label();
(<any>lbl).scrollableContent = false;
tabItem.view = lbl;
tabView.items = [tabItem];
@@ -94,24 +101,28 @@ export function test_correct_layout_scrollable_content_false() {
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
let pageHeight = getHeight(page);
let expectedPageHeight = screenHeight - statusBarHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight - statusBar");
let expectedPageHeight = screenHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight");
let contentHeight = getHeight(lbl);
let contentNativeHeight = getNativeHeight(lbl);
let expectedLabelHeight = screenHeight - statusBarHeight - tabBarHeight;
TKUnit.assertEqual(contentHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBar - tabBar");
TKUnit.assertEqual(contentNativeHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBar - tabBar");
page.actionBarHidden = false;
TKUnit.waitUntilReady(() => page.isLayoutValid);
pageHeight = getHeight(page);
const navBarHeight = uiUtils.ios.getActualHeight(page.frame.ios.controller.navigationBar);
expectedPageHeight = screenHeight - statusBarHeight - navBarHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight - statusBar - navBarHeight");
expectedPageHeight = screenHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight");
contentHeight = getHeight(lbl);
contentNativeHeight = getNativeHeight(lbl);
expectedLabelHeight = screenHeight - statusBarHeight - tabBarHeight - navBarHeight;
TKUnit.assertEqual(contentHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBarHeight - tabBarHeight - navBarHeight");
TKUnit.assertEqual(contentNativeHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBarHeight - tabBarHeight - navBarHeight");
}
export function test_correct_layout_scrollable_content_true() {
@@ -137,12 +148,12 @@ export function test_correct_layout_scrollable_content_true() {
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
let pageHeight = getHeight(page);
let expectedPageHeight = screenHeight - statusBarHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight - statusBar");
let expectedPageHeight = screenHeight;
TKUnit.assertEqual(pageHeight, expectedPageHeight, "page.height !== screenHeight");
let contentHeight = getHeight(lbl);
let expectedLabelHeight = screenHeight - statusBarHeight;
TKUnit.assertEqual(contentHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBar - tabBar");
TKUnit.assertEqual(contentHeight, expectedLabelHeight, "lbl.height !== screenHeight - statusBar");
page.actionBarHidden = false;
TKUnit.waitUntilReady(() => page.isLayoutValid);

View File

@@ -1,26 +1,26 @@
import * as TKUnit from "../../TKUnit";
import * as app from "tns-core-modules/application";
import * as button from "tns-core-modules/ui/button";
import * as testModule from "../../ui-test";
import { Button } from "tns-core-modules/ui/button";
import { Page, isIOS } from "tns-core-modules/ui/page";
import { UITest } from "../../ui-test";
import * as layoutHelper from "../layouts/layout-helper";
import { Page } from "tns-core-modules/ui/page";
import * as frame from "tns-core-modules/ui/frame";
import * as helper from "../helper";
// >> article-require-scrollview-module
import * as scrollViewModule from "tns-core-modules/ui/scroll-view";
import { ScrollView, ScrollEventData } from "tns-core-modules/ui/scroll-view";
// << article-require-scrollview-module
class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
class ScrollLayoutTest extends UITest<ScrollView> {
public create(): scrollViewModule.ScrollView {
let scrollView = new scrollViewModule.ScrollView();
public create(): ScrollView {
const scrollView = new ScrollView();
scrollView.orientation = "vertical";
scrollView.width = { value: 200, unit: "px" };
scrollView.height = { value: 300, unit: "px" };
let btn = new button.Button();
const btn = new Button();
btn.text = "test";
btn.width = { value: 500, unit: "px" };
btn.height = { value: 500, unit: "px" };
@@ -31,13 +31,13 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
public test_snippets() {
// >> article-creating-scrollview
var scrollView = new scrollViewModule.ScrollView();
const scrollView = new ScrollView();
// << article-creating-scrollview
TKUnit.assertTrue(scrollView !== null, "ScrollView should be created.");
}
public test_default_TNS_values() {
let scroll = new scrollViewModule.ScrollView();
const scroll = new ScrollView();
TKUnit.assertEqual(scroll.orientation, "vertical", "Default this.testView.orientation");
TKUnit.assertEqual(scroll.verticalOffset, 0, "Default this.testView.verticalOffset");
TKUnit.assertEqual(scroll.horizontalOffset, 0, "Default this.testView.horizontalOffset");
@@ -46,22 +46,20 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
public test_vertical_oriantation_creates_correct_native_view() {
this.testView.orientation = "vertical";
if (app.android) {
TKUnit.assert(this.testView.android instanceof org.nativescript.widgets.VerticalScrollView, "android property should be instanceof org.nativescript.widgets.VerticalScrollView");
}
else if (app.ios) {
if (isIOS) {
TKUnit.assert(this.testView.ios instanceof UIScrollView, "ios property is UIScrollView");
} else {
TKUnit.assert(this.testView.android instanceof org.nativescript.widgets.VerticalScrollView, "android property should be instanceof org.nativescript.widgets.VerticalScrollView");
}
}
public test_horizontal_oriantation_creates_correct_native_view() {
this.testView.orientation = "horizontal";
if (app.android) {
TKUnit.assert(this.testView.android instanceof org.nativescript.widgets.HorizontalScrollView, "android property should be instanceof org.nativescript.widgets.HorizontalScrollView");
}
else if (app.ios) {
if (isIOS) {
TKUnit.assert(this.testView.ios instanceof UIScrollView, "ios property is UIScrollView");
} else {
TKUnit.assert(this.testView.android instanceof org.nativescript.widgets.HorizontalScrollView, "android property should be instanceof org.nativescript.widgets.HorizontalScrollView");
}
}
@@ -102,28 +100,18 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
}
public test_scrollToVerticalOffset_no_animation() {
TKUnit.assertEqual(this.testView.verticalOffset, 0, "this.testView.verticalOffset");
this.waitUntilTestElementLayoutIsValid();
// NOTE: when automaticallyAdjustsScrollViewInsets is true (which is the default value)
// ScrollView verticalOffset is 20.
// TKUnit.assertEqual(this.testView.verticalOffset, 0, "this.testView.verticalOffset");
this.testView.scrollToVerticalOffset(layoutHelper.dp(100), false);
TKUnit.assertAreClose(layoutHelper.dip(this.testView.verticalOffset), 100, 0.1, "this.testView.verticalOffset");
}
public test_scrollToVerticalOffset_with_animation() {
TKUnit.assertEqual(this.testView.verticalOffset, 0, "this.testView.verticalOffset");
this.waitUntilTestElementLayoutIsValid();
// NOTE: when automaticallyAdjustsScrollViewInsets is true (which is the default value)
// ScrollView verticalOffset is 20.
// TKUnit.assertEqual(this.testView.verticalOffset, 0, "this.testView.verticalOffset");
this.testView.scrollToVerticalOffset(layoutHelper.dp(100), true);
// No synchronous change.
// NOTE: when automaticallyAdjustsScrollViewInsets is true (which is the default value)
// ScrollView verticalOffset is 20.
// TKUnit.assertEqual(this.testView.verticalOffset, 0, "this.testView.verticalOffset");
TKUnit.waitUntilReady(() => { return TKUnit.areClose(layoutHelper.dip(this.testView.verticalOffset), 100, 0.9); });
// The scrolling animation should be finished by now
@@ -158,17 +146,15 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
public test_scrollView_persistsState_vertical() {
this.waitUntilTestElementLayoutIsValid();
this.testView.scrollToVerticalOffset(layoutHelper.dp(100), false);
TKUnit.assertAreClose(layoutHelper.dip(this.testView.verticalOffset), 100, 0.1, "this.testView.verticalOffset before navigation");
const expected = layoutHelper.dp(100);
this.testView.scrollToVerticalOffset(expected, false);
// TKUnit.assertAreClose(this.testView.verticalOffset, expected, 0.1, "this.testView.verticalOffset before navigation");
helper.navigateWithHistory(() => new Page());
helper.goBack();
// Wait for the page to reload.
TKUnit.waitUntilReady(() => { return TKUnit.areClose(layoutHelper.dip(this.testView.verticalOffset), 100, 0.1); });
// Check verticalOffset after navigation
TKUnit.assertAreClose(layoutHelper.dip(this.testView.verticalOffset), 100, 0.1, "this.testView.verticalOffset after navigation");
TKUnit.assertAreClose(this.testView.verticalOffset, expected, 0.1, "this.testView.verticalOffset after navigation");
}
public test_scrollView_persistsState_horizontal() {
@@ -178,16 +164,17 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.scrollToHorizontalOffset(layoutHelper.dp(100), false);
TKUnit.assertAreClose(layoutHelper.dip(this.testView.horizontalOffset), 100, 0.1, "this.testView.horizontalOffset before navigation");
helper.navigateWithHistory(() => new Page());
helper.goBack();
// Check verticalOffset after navigation
// Check horizontalOffset after navigation
TKUnit.assertAreClose(layoutHelper.dip(this.testView.horizontalOffset), 100, 0.1, "this.testView.horizontalOffset after navigation");
}
public test_scrollView_vertical_raised_scroll_event() {
var scrollY: number;
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
this.testView.on(ScrollView.scrollEvent, (args: ScrollEventData) => {
scrollY = args.scrollY;
});
@@ -202,7 +189,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.orientation = "horizontal";
var scrollX: number;
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
this.testView.on(ScrollView.scrollEvent, (args: ScrollEventData) => {
scrollX = args.scrollX;
});
@@ -217,7 +204,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.waitUntilTestElementLayoutIsValid();
var scrollY: number;
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
this.testView.on(ScrollView.scrollEvent, (args: ScrollEventData) => {
scrollY = args.scrollY;
});
@@ -232,7 +219,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.waitUntilTestElementLayoutIsValid();
var scrollX: number;
this.testView.on(scrollViewModule.ScrollView.scrollEvent, (args: scrollViewModule.ScrollEventData) => {
this.testView.on(ScrollView.scrollEvent, (args: ScrollEventData) => {
scrollX = args.scrollX;
});
@@ -249,7 +236,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.scrollBarIndicatorVisible = true;
this.waitUntilTestElementLayoutIsValid();
if (app.ios) {
if (isIOS) {
TKUnit.assertEqual(this.testView.ios.showsHorizontalScrollIndicator, true);
} else {
TKUnit.assertEqual(this.testView.android.isHorizontalScrollBarEnabled(), true);
@@ -258,7 +245,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.scrollBarIndicatorVisible = false;
this.waitUntilTestElementLayoutIsValid();
if (app.ios) {
if (isIOS) {
TKUnit.assertEqual(this.testView.ios.showsHorizontalScrollIndicator, false);
} else {
TKUnit.assertEqual(this.testView.android.isHorizontalScrollBarEnabled(), false);
@@ -270,7 +257,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.scrollBarIndicatorVisible = true;
this.waitUntilTestElementLayoutIsValid();
if (app.ios) {
if (isIOS) {
TKUnit.assertEqual(this.testView.ios.showsVerticalScrollIndicator, true);
} else {
TKUnit.assertEqual(this.testView.android.isVerticalScrollBarEnabled(), true);
@@ -279,7 +266,7 @@ class ScrollLayoutTest extends testModule.UITest<scrollViewModule.ScrollView> {
this.testView.scrollBarIndicatorVisible = false;
this.waitUntilTestElementLayoutIsValid();
if (app.ios) {
if (isIOS) {
TKUnit.assertEqual(this.testView.ios.showsVerticalScrollIndicator, false);
} else {
TKUnit.assertEqual(this.testView.android.isVerticalScrollBarEnabled(), false);

View File

@@ -246,7 +246,7 @@ function _clickTheFirstButtonInTheListViewNatively(tabView: TabView) {
button.performClick();
}
else {
const tableView = <UITableView>tabView.ios.viewControllers[0].view;
const tableView = <UITableView>tabView.ios.selectedViewController.view.subviews[0];
const cell = <UITableViewCell>tableView.cellForRowAtIndexPath(NSIndexPath.indexPathForItemInSection(0, 0));
const btn = <UIButton>cell.contentView.subviews[0];
btn.sendActionsForControlEvents(UIControlEvents.TouchUpInside);