mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 20:11:24 +08:00
Merge pull request #267 from NativeScript/hhristov/ios-issues
Fix iOS transition issue
This commit is contained in:
@ -194,7 +194,6 @@ export function navigateToModule(moduleName: string) {
|
|||||||
frame.topmost().navigate({ moduleName: moduleName, animated: false });
|
frame.topmost().navigate({ moduleName: moduleName, animated: false });
|
||||||
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
TKUnit.waitUntilReady(() => { return frame.topmost().currentPage !== currentPage; });
|
||||||
TKUnit.assert(frame.topmost().currentPage.isLoaded, "Current page should be loaded!");
|
TKUnit.assert(frame.topmost().currentPage.isLoaded, "Current page should be loaded!");
|
||||||
TKUnit.assert(!currentPage.isLoaded, "Previous page should be unloaded!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goBack(): void {
|
export function goBack(): void {
|
||||||
|
@ -248,4 +248,4 @@ export var test_SettingStretch_none = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
helper.buildUIAndRunTest(image, testFunc);
|
helper.buildUIAndRunTest(image, testFunc);
|
||||||
}
|
}
|
@ -87,6 +87,24 @@ export var test_Set_Text_Native = function () {
|
|||||||
helper.buildUIAndRunTest(label, test);
|
helper.buildUIAndRunTest(label, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export var test_measuredWidth_is_not_clipped = function () {
|
||||||
|
var label = new LabelModule.Label();
|
||||||
|
label.horizontalAlignment = "left";
|
||||||
|
label.text = "i";
|
||||||
|
label.fontSize = 9;
|
||||||
|
|
||||||
|
var test = function (views: Array<view.View>) {
|
||||||
|
|
||||||
|
TKUnit.waitUntilReady(() => { return label.isLayoutValid; });
|
||||||
|
|
||||||
|
var expectedValue = 3;
|
||||||
|
var measuredWidth = label.getMeasuredWidth();
|
||||||
|
TKUnit.assertEqual(measuredWidth, expectedValue, "measuredWidth should not be rounded down.");
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.buildUIAndRunTest(label, test);
|
||||||
|
}
|
||||||
|
|
||||||
export var test_Set_TextWrap_TNS = function () {
|
export var test_Set_TextWrap_TNS = function () {
|
||||||
// <snippet module="ui/label" title="Label">
|
// <snippet module="ui/label" title="Label">
|
||||||
// ### How to turn on text wrapping for a label
|
// ### How to turn on text wrapping for a label
|
||||||
|
@ -476,7 +476,7 @@ export class View extends proxy.ProxyObject implements definition.View {
|
|||||||
|
|
||||||
case utils.layout.AT_MOST:
|
case utils.layout.AT_MOST:
|
||||||
if (specSize < size) {
|
if (specSize < size) {
|
||||||
result = Math.round(specSize) | utils.layout.MEASURED_STATE_TOO_SMALL;
|
result = Math.round(specSize + 0.499) | utils.layout.MEASURED_STATE_TOO_SMALL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -485,7 +485,7 @@ export class View extends proxy.ProxyObject implements definition.View {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.round(result) | (childMeasuredState & utils.layout.MEASURED_STATE_MASK);
|
return Math.round(result + 0.499) | (childMeasuredState & utils.layout.MEASURED_STATE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static layoutChild(parent: View, child: View, left: number, top: number, right: number, bottom: number): void {
|
public static layoutChild(parent: View, child: View, left: number, top: number, right: number, bottom: number): void {
|
||||||
|
@ -182,7 +182,7 @@ class PageFragmentBody extends android.app.Fragment {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import trace = require("trace");
|
|||||||
import imageSource = require("image-source");
|
import imageSource = require("image-source");
|
||||||
import pages = require("ui/page");
|
import pages = require("ui/page");
|
||||||
import enums = require("ui/enums");
|
import enums = require("ui/enums");
|
||||||
|
import utils = require("utils/utils");
|
||||||
|
import view = require("ui/core/view");
|
||||||
|
|
||||||
declare var exports;
|
declare var exports;
|
||||||
require("utils/module-merge").merge(frameCommon, exports);
|
require("utils/module-merge").merge(frameCommon, exports);
|
||||||
@ -15,7 +17,8 @@ var navDepth = 0;
|
|||||||
export class Frame extends frameCommon.Frame {
|
export class Frame extends frameCommon.Frame {
|
||||||
private _ios: iOSFrame;
|
private _ios: iOSFrame;
|
||||||
private _paramToNavigate: any;
|
private _paramToNavigate: any;
|
||||||
public shouldSkipNativePop: boolean = false;
|
public _shouldSkipNativePop: boolean = false;
|
||||||
|
public _navigateToEntry: definition.BackstackEntry;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -39,7 +42,7 @@ export class Frame extends frameCommon.Frame {
|
|||||||
this._paramToNavigate = param;
|
this._paramToNavigate = param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||||
var viewController = backstackEntry.resolvedPage.ios;
|
var viewController = backstackEntry.resolvedPage.ios;
|
||||||
if (!viewController) {
|
if (!viewController) {
|
||||||
@ -63,7 +66,7 @@ export class Frame extends frameCommon.Frame {
|
|||||||
public _goBackCore(entry: definition.NavigationEntry) {
|
public _goBackCore(entry: definition.NavigationEntry) {
|
||||||
navDepth--;
|
navDepth--;
|
||||||
trace.write("Frame<" + this._domId + ">.popViewControllerAnimated depth = " + navDepth, trace.categories.Navigation);
|
trace.write("Frame<" + this._domId + ">.popViewControllerAnimated depth = " + navDepth, trace.categories.Navigation);
|
||||||
if (!this.shouldSkipNativePop) {
|
if (!this._shouldSkipNativePop) {
|
||||||
this._ios.controller.popViewControllerAnimated(this._getIsAnimatedNavigation(entry));
|
this._ios.controller.popViewControllerAnimated(this._getIsAnimatedNavigation(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +112,32 @@ export class Frame extends frameCommon.Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||||
|
|
||||||
|
var width = utils.layout.getMeasureSpecSize(widthMeasureSpec);
|
||||||
|
var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec);
|
||||||
|
|
||||||
|
var height = utils.layout.getMeasureSpecSize(heightMeasureSpec);
|
||||||
|
var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec);
|
||||||
|
|
||||||
|
var result = view.View.measureChild(this, this.currentPage, widthMeasureSpec, utils.layout.makeMeasureSpec(height - this.navigationBarHeight, heightMode));
|
||||||
|
if (this._navigateToEntry) {
|
||||||
|
view.View.measureChild(this, this._navigateToEntry.resolvedPage, widthMeasureSpec, utils.layout.makeMeasureSpec(height - this.navigationBarHeight, heightMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
var widthAndState = view.View.resolveSizeAndState(result.measuredWidth, width, widthMode, 0);
|
||||||
|
var heightAndState = view.View.resolveSizeAndState(result.measuredHeight, height, heightMode, 0);
|
||||||
|
|
||||||
|
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||||
|
view.View.layoutChild(this, this.currentPage, 0, this.navigationBarHeight, right - left, bottom - top);
|
||||||
|
if (this._navigateToEntry) {
|
||||||
|
view.View.layoutChild(this, this._navigateToEntry.resolvedPage, 0, this.navigationBarHeight, right - left, bottom - top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public layoutNativeView(left: number, top: number, right: number, bottom: number): void {
|
public layoutNativeView(left: number, top: number, right: number, bottom: number): void {
|
||||||
// We don't call super here because we set frame on our first subview.
|
// We don't call super here because we set frame on our first subview.
|
||||||
// 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.
|
// 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.
|
||||||
@ -196,6 +225,21 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
|||||||
this._owner._updateLayout();
|
this._owner._updateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public navigationControllerWillShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
||||||
|
// In this method we need to layout the new page otherwise page will be shown empty and update after that which is bad UX.
|
||||||
|
var frame = this._owner;
|
||||||
|
var newEntry: definition.BackstackEntry = viewController[ENTRY];
|
||||||
|
var newPage = newEntry.resolvedPage;
|
||||||
|
if (!newPage.parent) {
|
||||||
|
frame._navigateToEntry = newEntry;
|
||||||
|
frame._addView(newPage);
|
||||||
|
frame.populateMenuItems(newPage);
|
||||||
|
}
|
||||||
|
else if (newPage.parent !== frame) {
|
||||||
|
throw new Error("Page is already shown on another frame.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public navigationControllerDidShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
public navigationControllerDidShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
||||||
|
|
||||||
var frame: Frame = this._owner;
|
var frame: Frame = this._owner;
|
||||||
@ -203,28 +247,30 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
|
|||||||
var currentEntry = backStack.length > 0 ? backStack[backStack.length - 1] : null;
|
var currentEntry = backStack.length > 0 ? backStack[backStack.length - 1] : null;
|
||||||
var newEntry: definition.BackstackEntry = viewController[ENTRY];
|
var newEntry: definition.BackstackEntry = viewController[ENTRY];
|
||||||
|
|
||||||
if (newEntry === currentEntry && currentEntry) {
|
// This code check if navigation happened through UI (e.g. back button or swipe gesture).
|
||||||
|
// When calling goBack on frame isBack will be false.
|
||||||
|
var isBack: boolean = currentEntry && newEntry === currentEntry;
|
||||||
|
if (isBack) {
|
||||||
try {
|
try {
|
||||||
frame.shouldSkipNativePop = true;
|
frame._shouldSkipNativePop = true;
|
||||||
frame.goBack();
|
frame.goBack();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
frame.shouldSkipNativePop = false;
|
frame._shouldSkipNativePop = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var page = frame.currentPage;
|
var page = frame.currentPage;
|
||||||
if (page) {
|
if (page && !navigationController.viewControllers.containsObject(page.ios)) {
|
||||||
frame._removeView(page);
|
frame._removeView(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newPage = newEntry.resolvedPage;
|
frame._navigateToEntry = null;
|
||||||
|
|
||||||
frame._currentEntry = newEntry;
|
frame._currentEntry = newEntry;
|
||||||
frame._addView(newPage);
|
|
||||||
frame.populateMenuItems(newPage);
|
|
||||||
frame.updateNavigationBar();
|
frame.updateNavigationBar();
|
||||||
|
|
||||||
|
var newPage = newEntry.resolvedPage;
|
||||||
|
|
||||||
// notify the page
|
// notify the page
|
||||||
newPage.onNavigatedTo(newEntry.entry.context);
|
newPage.onNavigatedTo(newEntry.entry.context);
|
||||||
frame._processNavigationQueue(newPage);
|
frame._processNavigationQueue(newPage);
|
||||||
|
@ -65,6 +65,7 @@ export class Image extends view.View implements definition.Image {
|
|||||||
IMAGE,
|
IMAGE,
|
||||||
new proxy.PropertyMetadata(
|
new proxy.PropertyMetadata(
|
||||||
undefined,
|
undefined,
|
||||||
|
// None on purpose. for iOS we trigger it manually if needed. Android layout handles it.
|
||||||
dependencyObservable.PropertyMetadataSettings.None
|
dependencyObservable.PropertyMetadataSettings.None
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
8
ui/image/image.d.ts
vendored
8
ui/image/image.d.ts
vendored
@ -10,8 +10,8 @@ declare module "ui/image" {
|
|||||||
* Represents a class that provides functionality for loading and streching image(s).
|
* Represents a class that provides functionality for loading and streching image(s).
|
||||||
*/
|
*/
|
||||||
export class Image extends view.View {
|
export class Image extends view.View {
|
||||||
public static urlProperty: dependencyObservable.Property;
|
public static srcProperty: dependencyObservable.Property;
|
||||||
public static sourceProperty: dependencyObservable.Property;
|
public static imageSourceProperty: dependencyObservable.Property;
|
||||||
public static isLoadingProperty: dependencyObservable.Property;
|
public static isLoadingProperty: dependencyObservable.Property;
|
||||||
public static stretchProperty: dependencyObservable.Property;
|
public static stretchProperty: dependencyObservable.Property;
|
||||||
|
|
||||||
@ -53,12 +53,12 @@ declare module "ui/image" {
|
|||||||
/**
|
/**
|
||||||
* Gets or sets the image source of the image.
|
* Gets or sets the image source of the image.
|
||||||
*/
|
*/
|
||||||
source: imageSource.ImageSource;
|
imageSource: imageSource.ImageSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the URL of the image.
|
* Gets or sets the URL of the image.
|
||||||
*/
|
*/
|
||||||
url: string;
|
src: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the image stretch mode. Possible values are contained in the [Stretch enumeration](../enums/Stretch/README.md).
|
* Gets or sets the image stretch mode. Possible values are contained in the [Stretch enumeration](../enums/Stretch/README.md).
|
||||||
|
@ -186,7 +186,7 @@ export class ListView extends common.ListView {
|
|||||||
|
|
||||||
public refresh() {
|
public refresh() {
|
||||||
this._ios.reloadData();
|
this._ios.reloadData();
|
||||||
this.requestLayout();
|
this.requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getHeight(index: number): number {
|
public getHeight(index: number): number {
|
||||||
@ -227,21 +227,22 @@ export class ListView extends common.ListView {
|
|||||||
|
|
||||||
public _prepareCell(tableCell: UITableViewCell, indexPath: NSIndexPath): number {
|
public _prepareCell(tableCell: UITableViewCell, indexPath: NSIndexPath): number {
|
||||||
var cell: any = tableCell;
|
var cell: any = tableCell;
|
||||||
if (!cell.view) {
|
|
||||||
cell.view = this._getItemTemplateContent(indexPath.row);
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = notifyForItemAtIndex(this, cell, ITEMLOADING, indexPath);
|
|
||||||
var view = cell.view = args.view || this._getDefaultItemContent(indexPath.row);
|
|
||||||
|
|
||||||
if (view && !view.parent && view.ios) {
|
|
||||||
cell.contentView.addSubview(view.ios);
|
|
||||||
this._addView(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
var cellHeight: number;
|
var cellHeight: number;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._preparingCell = true;
|
this._preparingCell = true;
|
||||||
|
if (!cell.view) {
|
||||||
|
cell.view = this._getItemTemplateContent(indexPath.row);
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = notifyForItemAtIndex(this, cell, ITEMLOADING, indexPath);
|
||||||
|
var view = cell.view = args.view || this._getDefaultItemContent(indexPath.row);
|
||||||
|
|
||||||
|
if (view && !view.parent && view.ios) {
|
||||||
|
cell.contentView.addSubview(view.ios);
|
||||||
|
this._addView(view);
|
||||||
|
}
|
||||||
|
|
||||||
this._prepareItem(view, indexPath.row);
|
this._prepareItem(view, indexPath.row);
|
||||||
cellHeight = this._layoutCell(view, indexPath);
|
cellHeight = this._layoutCell(view, indexPath);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user