From 84e973d6a8c1e183fe27049551188839fdc22dfa Mon Sep 17 00:00:00 2001 From: SvetoslavTsenov Date: Fri, 26 Oct 2018 18:02:41 +0300 Subject: [PATCH 01/16] chore: bump version --- tns-core-modules/package.json | 4 ++-- tns-platform-declarations/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json index ec101a84b5..8e72fa7095 100644 --- a/tns-core-modules/package.json +++ b/tns-core-modules/package.json @@ -1,7 +1,7 @@ { "name": "tns-core-modules", "description": "Telerik NativeScript Core Modules", - "version": "5.1.0", + "version": "5.0.0", "homepage": "https://www.nativescript.org", "repository": { "type": "git", @@ -26,7 +26,7 @@ "license": "Apache-2.0", "typings": "tns-core-modules.d.ts", "dependencies": { - "tns-core-modules-widgets": "next", + "tns-core-modules-widgets": "5.0.1", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/tns-platform-declarations/package.json b/tns-platform-declarations/package.json index 2025046f02..2485da6475 100644 --- a/tns-platform-declarations/package.json +++ b/tns-platform-declarations/package.json @@ -1,6 +1,6 @@ { "name": "tns-platform-declarations", - "version": "5.1.0", + "version": "5.0.0", "description": "Platform-specific TypeScript declarations for NativeScript for accessing native objects", "main": "", "scripts": { From c217f12c8f65f2873d3c42350a9449d0bd0f6446 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Fri, 26 Oct 2018 13:32:30 +0300 Subject: [PATCH 02/16] fix-next(android): exit fragment animation (#6421) --- .../ui/frame/fragment.transitions.android.ts | 5 +- tns-core-modules/ui/frame/frame.android.ts | 74 +++++++++++++++---- .../ui/tab-view/tab-view.android.ts | 7 +- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/tns-core-modules/ui/frame/fragment.transitions.android.ts b/tns-core-modules/ui/frame/fragment.transitions.android.ts index bfb61ea505..43eefeeff3 100644 --- a/tns-core-modules/ui/frame/fragment.transitions.android.ts +++ b/tns-core-modules/ui/frame/fragment.transitions.android.ts @@ -151,7 +151,8 @@ export function _setAndroidFragmentTransitions( // Having transition means we have custom animation if (transition) { - fragmentTransaction.setCustomAnimations(AnimationType.enterFakeResourceId, AnimationType.exitFakeResourceId, AnimationType.popEnterFakeResourceId, AnimationType.popExitFakeResourceId); + // we do not use Android backstack so setting popEnter / popExit is meaningless (3rd and 4th optional args) + fragmentTransaction.setCustomAnimations(AnimationType.enterFakeResourceId, AnimationType.exitFakeResourceId); setupAllAnimation(newEntry, transition); if (currentFragmentNeedsDifferentAnimation) { setupExitAndPopEnterAnimation(currentEntry, transition); @@ -375,7 +376,7 @@ function clearAnimationListener(animator: ExpandedAnimator, listener: android.an animator.removeListener(listener); - if (traceEnabled()) { + if (animator.entry && traceEnabled()) { const entry = animator.entry; traceWrite(`Clear ${animator.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition); } diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index 2e2d7e65fd..bfb911d2cb 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -24,6 +24,14 @@ import { createViewFromEntry } from "../builder"; export * from "./frame-common"; +interface AnimatorState { + enterAnimator: android.animation.Animator; + exitAnimator: android.animation.Animator; + popEnterAnimator: android.animation.Animator; + popExitAnimator: android.animation.Animator; + transitionName: string; +} + const INTENT_EXTRA = "com.tns.activity"; const ROOT_VIEW_ID_EXTRA = "com.tns.activity.rootViewId"; const FRAMEID = "_frameId"; @@ -93,6 +101,7 @@ export class Frame extends FrameBase { private _tearDownPending = false; private _attachedToWindow = false; public _isBack: boolean = true; + private _cachedAnimatorState: AnimatorState; constructor() { super(); @@ -170,6 +179,17 @@ export class Frame extends FrameBase { const entry = this._currentEntry; if (entry && manager && !manager.findFragmentByTag(entry.fragmentTag)) { // Simulate first navigation (e.g. no animations or transitions) + // we need to cache the original animation settings so we can restore them later; otherwise as the + // simulated first navigation is not animated (it is actually a zero duration animator) the "popExit" animation + // is broken when transaction.setCustomAnimations(...) is used in a scenario with: + // 1) forward navigation + // 2) suspend / resume app + // 3) back navigation -- the exiting fragment is erroneously animated with the exit animator from the + // simulated navigation (NoTransition, zero duration animator) and thus the fragment immediately disappears; + // the user only sees the animation of the entering fragment as per its specific enter animation settings. + // NOTE: we are restoring the animation settings in Frame.setCurrent(...) as navigation completes asynchronously + this._cachedAnimatorState = getAnimatorState(this._currentEntry); + this._currentEntry = null; // NavigateCore will eventually call _processNextNavigationEntry again. this._navigateCore(entry); @@ -194,8 +214,12 @@ export class Frame extends FrameBase { } onUnloaded() { - this.disposeCurrentFragment(); super.onUnloaded(); + + // calling dispose fragment after super.onUnloaded() means we are not relying on the built-in Android logic + // to automatically remove child fragments when parent fragment is removed; + // this fixes issue with missing nested fragment on app suspend / resume; + this.disposeCurrentFragment(); } private disposeCurrentFragment(): void { @@ -278,6 +302,14 @@ export class Frame extends FrameBase { // Continue with next item in the queue. this._processNextNavigationEntry(); } + + // restore cached animation settings if we just completed simulated first navigation (no animation) + if (this._cachedAnimatorState) { + restoreAnimatorState(this._currentEntry, this._cachedAnimatorState); + + this._cachedAnimatorState = null; + } + } public onBackPressed(): boolean { @@ -332,7 +364,7 @@ export class Frame extends FrameBase { const newFragmentTag = `fragment${fragmentId}[${navDepth}]`; const newFragment = this.createFragment(newEntry, newFragmentTag); const transaction = manager.beginTransaction(); - const animated = this._getIsAnimatedNavigation(newEntry.entry); + const animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false; // NOTE: Don't use transition for the initial navigation (same as on iOS) // On API 21+ transition won't be triggered unless there was at least one // layout pass so we will wait forever for transitionCompleted handler... @@ -346,7 +378,7 @@ export class Frame extends FrameBase { } transaction.replace(this.containerViewId, newFragment, newFragmentTag); - transaction.commit(); + transaction.commitAllowingStateLoss(); } public _goBackCore(backstackEntry: BackstackEntry) { @@ -369,11 +401,12 @@ export class Frame extends FrameBase { const transitionReversed = _reverseTransitions(backstackEntry, this._currentEntry); if (!transitionReversed) { // If transition were not reversed then use animations. - transaction.setCustomAnimations(AnimationType.popEnterFakeResourceId, AnimationType.popExitFakeResourceId, AnimationType.enterFakeResourceId, AnimationType.exitFakeResourceId); + // we do not use Android backstack so setting popEnter / popExit is meaningless (3rd and 4th optional args) + transaction.setCustomAnimations(AnimationType.popEnterFakeResourceId, AnimationType.popExitFakeResourceId); } transaction.replace(this.containerViewId, backstackEntry.fragment, backstackEntry.fragmentTag); - transaction.commit(); + transaction.commitAllowingStateLoss(); } public _removeEntry(removed: BackstackEntry): void { @@ -470,6 +503,27 @@ export class Frame extends FrameBase { } } +function getAnimatorState(entry: BackstackEntry): AnimatorState { + const expandedEntry = entry; + const animatorState = {}; + animatorState.enterAnimator = expandedEntry.enterAnimator; + animatorState.exitAnimator = expandedEntry.exitAnimator; + animatorState.popEnterAnimator = expandedEntry.popEnterAnimator; + animatorState.popExitAnimator = expandedEntry.popExitAnimator; + animatorState.transitionName = expandedEntry.transitionName; + + return animatorState; +} + +function restoreAnimatorState(entry: BackstackEntry, snapshot: AnimatorState): void { + const expandedEntry = entry; + expandedEntry.enterAnimator = snapshot.enterAnimator; + expandedEntry.exitAnimator = snapshot.exitAnimator; + expandedEntry.popEnterAnimator = snapshot.popEnterAnimator; + expandedEntry.popExitAnimator = snapshot.popExitAnimator; + expandedEntry.transitionName = snapshot.transitionName; +} + function clearEntry(entry: BackstackEntry): void { if (entry.fragment) { _clearFragment(entry); @@ -786,16 +840,6 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks { traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle); } - // fixes 'java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first'. - // on app resume in nested frame scenarios with support library version greater than 26.0.0 - const view = fragment.getView(); - if (view != null) { - const viewParent = view.getParent(); - if (viewParent instanceof android.view.ViewGroup) { - viewParent.removeView(view); - } - } - superFunc.call(fragment); } diff --git a/tns-core-modules/ui/tab-view/tab-view.android.ts b/tns-core-modules/ui/tab-view/tab-view.android.ts index f12e115acb..041b7a7161 100644 --- a/tns-core-modules/ui/tab-view/tab-view.android.ts +++ b/tns-core-modules/ui/tab-view/tab-view.android.ts @@ -317,8 +317,13 @@ export class TabViewItem extends TabViewItemBase { } } + // TODO: can happen in a modal tabview scenario when the modal dialog fragment is already removed if (!tabFragment) { - throw new Error(`Could not get child fragment manager for tab item with index ${this.index}`); + if (traceEnabled()) { + traceWrite(`Could not get child fragment manager for tab item with index ${this.index}`, traceCategory); + } + + return (tabView)._getRootFragmentManager(); } return tabFragment.getChildFragmentManager(); From f2618347194e38e0478beb09dbb33817c03b6863 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Fri, 26 Oct 2018 14:05:14 +0300 Subject: [PATCH 03/16] fix-next: handle action bar safe area nesting (#6455) --- apps/app/ui-tests-app/main-page.ts | 1 + .../nested-frames/full-screen-n-n.xml | 10 +++++ .../nested-frames/full-screen-n-y.xml | 10 +++++ .../nested-frames/full-screen-y-n.xml | 10 +++++ .../nested-frames/full-screen-y-y.xml | 10 +++++ .../ui-tests-app/nested-frames/main-page.ts | 28 ++++++++++++++ .../ui-tests-app/nested-frames/main-page.xml | 6 +++ .../nested-frames/mid-screen-n-n.xml | 12 ++++++ .../nested-frames/mid-screen-n-y.xml | 12 ++++++ .../nested-frames/mid-screen-y-n.xml | 12 ++++++ .../nested-frames/mid-screen-y-y.xml | 12 ++++++ .../nested-frames/nested-page.xml | 13 +++++++ .../ui-tests-app/nested-frames/tab-n-n.xml | 14 +++++++ .../ui-tests-app/nested-frames/tab-n-y.xml | 14 +++++++ .../ui-tests-app/nested-frames/tab-y-n.xml | 14 +++++++ .../ui-tests-app/nested-frames/tab-y-y.xml | 14 +++++++ tns-core-modules/ui/core/view/view.ios.ts | 38 +++++++++++-------- tns-core-modules/ui/frame/frame.ios.ts | 2 +- tns-core-modules/ui/page/page.ios.ts | 24 ++++++++++++ 19 files changed, 240 insertions(+), 16 deletions(-) create mode 100644 apps/app/ui-tests-app/nested-frames/full-screen-n-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/full-screen-n-y.xml create mode 100644 apps/app/ui-tests-app/nested-frames/full-screen-y-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/full-screen-y-y.xml create mode 100644 apps/app/ui-tests-app/nested-frames/main-page.ts create mode 100644 apps/app/ui-tests-app/nested-frames/main-page.xml create mode 100644 apps/app/ui-tests-app/nested-frames/mid-screen-n-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/mid-screen-n-y.xml create mode 100644 apps/app/ui-tests-app/nested-frames/mid-screen-y-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/mid-screen-y-y.xml create mode 100644 apps/app/ui-tests-app/nested-frames/nested-page.xml create mode 100644 apps/app/ui-tests-app/nested-frames/tab-n-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/tab-n-y.xml create mode 100644 apps/app/ui-tests-app/nested-frames/tab-y-n.xml create mode 100644 apps/app/ui-tests-app/nested-frames/tab-y-y.xml diff --git a/apps/app/ui-tests-app/main-page.ts b/apps/app/ui-tests-app/main-page.ts index 027c174e38..1fd62f2a59 100644 --- a/apps/app/ui-tests-app/main-page.ts +++ b/apps/app/ui-tests-app/main-page.ts @@ -35,6 +35,7 @@ export function pageLoaded(args: EventData) { examples.set("webview", "web-view/main-page"); examples.set("progress-bar", "progress-bar/main-page"); examples.set("date-picker", "date-picker/date-picker"); + examples.set("nested-frames", "nested-frames/main-page"); page.bindingContext = new MainPageViewModel(wrapLayout, examples); const parent = page.getViewById("parentLayout"); diff --git a/apps/app/ui-tests-app/nested-frames/full-screen-n-n.xml b/apps/app/ui-tests-app/nested-frames/full-screen-n-n.xml new file mode 100644 index 0000000000..3260e8f935 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/full-screen-n-n.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/full-screen-n-y.xml b/apps/app/ui-tests-app/nested-frames/full-screen-n-y.xml new file mode 100644 index 0000000000..87b5d0c06d --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/full-screen-n-y.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/full-screen-y-n.xml b/apps/app/ui-tests-app/nested-frames/full-screen-y-n.xml new file mode 100644 index 0000000000..071ac75f04 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/full-screen-y-n.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/full-screen-y-y.xml b/apps/app/ui-tests-app/nested-frames/full-screen-y-y.xml new file mode 100644 index 0000000000..fd53bf93c1 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/full-screen-y-y.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/main-page.ts b/apps/app/ui-tests-app/nested-frames/main-page.ts new file mode 100644 index 0000000000..1c01b725c3 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/main-page.ts @@ -0,0 +1,28 @@ +import { EventData } from "tns-core-modules/data/observable"; +import { SubMainPageViewModel } from "../sub-main-page-view-model"; +import { WrapLayout } from "tns-core-modules/ui/layouts/wrap-layout"; +import { Page } from "tns-core-modules/ui/page"; + +export function pageLoaded(args: EventData) { + const page = args.object; + const wrapLayout = page.getViewById("wrapLayoutWithExamples"); + page.bindingContext = new SubMainPageViewModel(wrapLayout, loadExamples()); +} + +export function loadExamples() { + const examples = new Map(); + examples.set("full-screen-n-n", "nested-frames/full-screen-n-n"); + examples.set("full-screen-n-y", "nested-frames/full-screen-n-y"); + examples.set("full-screen-y-n", "nested-frames/full-screen-y-n"); + examples.set("full-screen-y-y", "nested-frames/full-screen-y-y"); + examples.set("mid-screen-n-n", "nested-frames/mid-screen-n-n"); + examples.set("mid-screen-n-y", "nested-frames/mid-screen-n-y"); + examples.set("mid-screen-y-n", "nested-frames/mid-screen-y-n"); + examples.set("mid-screen-y-y", "nested-frames/mid-screen-y-y"); + examples.set("tab-y-y", "nested-frames/tab-y-y"); + examples.set("tab-n-y", "nested-frames/tab-n-y"); + examples.set("tab-y-n", "nested-frames/tab-y-n"); + examples.set("tab-n-n", "nested-frames/tab-n-n"); + + return examples; +} \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/main-page.xml b/apps/app/ui-tests-app/nested-frames/main-page.xml new file mode 100644 index 0000000000..33306f0d02 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/main-page.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/mid-screen-n-n.xml b/apps/app/ui-tests-app/nested-frames/mid-screen-n-n.xml new file mode 100644 index 0000000000..4f9548a0f3 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/mid-screen-n-n.xml @@ -0,0 +1,12 @@ + + + + + + + + + + > + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/mid-screen-n-y.xml b/apps/app/ui-tests-app/nested-frames/mid-screen-n-y.xml new file mode 100644 index 0000000000..83d94d5e2d --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/mid-screen-n-y.xml @@ -0,0 +1,12 @@ + + + + + + + + + + > + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/mid-screen-y-n.xml b/apps/app/ui-tests-app/nested-frames/mid-screen-y-n.xml new file mode 100644 index 0000000000..09a1235336 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/mid-screen-y-n.xml @@ -0,0 +1,12 @@ + + + + + + + + + + > + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/mid-screen-y-y.xml b/apps/app/ui-tests-app/nested-frames/mid-screen-y-y.xml new file mode 100644 index 0000000000..80d59b599d --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/mid-screen-y-y.xml @@ -0,0 +1,12 @@ + + + + + + + + + + > + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/nested-page.xml b/apps/app/ui-tests-app/nested-frames/nested-page.xml new file mode 100644 index 0000000000..baa973660a --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/nested-page.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/tab-n-n.xml b/apps/app/ui-tests-app/nested-frames/tab-n-n.xml new file mode 100644 index 0000000000..4c90b270f7 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/tab-n-n.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/tab-n-y.xml b/apps/app/ui-tests-app/nested-frames/tab-n-y.xml new file mode 100644 index 0000000000..0f3b8096a1 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/tab-n-y.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/tab-y-n.xml b/apps/app/ui-tests-app/nested-frames/tab-y-n.xml new file mode 100644 index 0000000000..f9733fb124 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/tab-y-n.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/ui-tests-app/nested-frames/tab-y-y.xml b/apps/app/ui-tests-app/nested-frames/tab-y-y.xml new file mode 100644 index 0000000000..2d06aab715 --- /dev/null +++ b/apps/app/ui-tests-app/nested-frames/tab-y-y.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 13abd07666..0c1a5b15bb 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -704,21 +704,6 @@ export namespace ios { } export function layoutView(controller: UIViewController, owner: View): void { - if (majorVersion >= 11) { - // apply parent page additional top insets if any. The scenario is when there is a parent page with action bar. - const parentPage = getAncestor(owner, "Page"); - if (parentPage) { - const parentPageInsetsTop = parentPage.viewController.view.safeAreaInsets.top; - const currentInsetsTop = controller.view.safeAreaInsets.top; - const additionalInsetsTop = parentPageInsetsTop - currentInsetsTop; - - if (additionalInsetsTop > 0) { - const additionalInsets = new UIEdgeInsets({ top: additionalInsetsTop, left: 0, bottom: 0, right: 0 }); - controller.additionalSafeAreaInsets = additionalInsets; - } - } - } - let layoutGuide = controller.view.safeAreaLayoutGuide; if (!layoutGuide) { traceWrite(`safeAreaLayoutGuide during layout of ${owner}. Creating fallback constraints, but layout might be wrong.`, @@ -897,6 +882,29 @@ export namespace ios { super.viewDidLayoutSubviews(); const owner = this.owner.get(); if (owner) { + if (majorVersion >= 11) { + // Handle nested UILayoutViewController safe area application. + // Currently, UILayoutViewController can be nested only in a TabView. + // The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout). + const tabViewItem = owner.parent; + const tabView = tabViewItem && tabViewItem.parent; + const parent = tabView && tabView.parent; + if (parent) { + const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top; + const currentInsetsTop = this.view.safeAreaInsets.top; + const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0); + + const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom; + const currentInsetsBottom = this.view.safeAreaInsets.bottom; + const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0); + + if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) { + const additionalInsets = new UIEdgeInsets({ top: additionalInsetsTop, left: 0, bottom: additionalInsetsBottom, right: 0 }); + this.additionalSafeAreaInsets = additionalInsets; + } + } + } + layoutView(this, owner); } } diff --git a/tns-core-modules/ui/frame/frame.ios.ts b/tns-core-modules/ui/frame/frame.ios.ts index 7b826c421b..28ba4a2f60 100644 --- a/tns-core-modules/ui/frame/frame.ios.ts +++ b/tns-core-modules/ui/frame/frame.ios.ts @@ -602,7 +602,7 @@ class iOSFrame implements iOSFrameDefinition { } public set showNavigationBar(value: boolean) { this._showNavigationBar = value; - this._controller.setNavigationBarHiddenAnimated(!value, true); + this._controller.setNavigationBarHiddenAnimated(!value, !this._disableNavBarAnimation); } public get navBarVisibility(): "auto" | "never" | "always" { diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index 6d1e8f9c00..4e737ce361 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -217,6 +217,30 @@ class UIViewControllerImpl extends UIViewController { if (owner) { // layout(owner.actionBar) // layout(owner.content) + + if (majorVersion >= 11) { + // Handle nested Page safe area insets application. + // A Page is nested if its Frame has a parent. + // If the Page is nested, cross check safe area insets on top and bottom with Frame parent. + const frame = owner.parent; + // There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent. + const frameParent = frame && frame.parent; + if (frameParent) { + const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top; + const currentInsetsTop = this.view.safeAreaInsets.top; + const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0); + + const parentPageInsetsBottom = frameParent.nativeViewProtected.safeAreaInsets.bottom; + const currentInsetsBottom = this.view.safeAreaInsets.bottom; + const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0); + + if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) { + const additionalInsets = new UIEdgeInsets({ top: additionalInsetsTop, left: 0, bottom: additionalInsetsBottom, right: 0 }); + this.additionalSafeAreaInsets = additionalInsets; + } + } + } + iosView.layoutView(this, owner); } } From 127d6dd10439508fcc392deb6621f979e52d3945 Mon Sep 17 00:00:00 2001 From: daviditsygin Date: Fri, 26 Oct 2018 04:47:35 -0700 Subject: [PATCH 04/16] docs(iOS): update HtmlView documentation link (#6335) The old link was a 404. --- tns-core-modules/ui/html-view/html-view.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/html-view/html-view.d.ts b/tns-core-modules/ui/html-view/html-view.d.ts index dfebe1621e..f553ed7b2e 100644 --- a/tns-core-modules/ui/html-view/html-view.d.ts +++ b/tns-core-modules/ui/html-view/html-view.d.ts @@ -7,7 +7,7 @@ import { View, Property } from "../core/view"; /** * Represents a view with html content. Use this component instead WebView when you want to show just static HTML content. - * [iOS support](https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSAttributedString_UIKit_Additions/#//apple_ref/occ/instm/NSAttributedString/initWithData:options:documentAttributes:error:) + * [iOS support](https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata) * [android support](http://developer.android.com/reference/android/text/Html.html) */ export class HtmlView extends View { From 7f45c0195ca3056744bfabbb898ff043b1444034 Mon Sep 17 00:00:00 2001 From: Todor Petrov Date: Fri, 26 Oct 2018 17:03:23 +0300 Subject: [PATCH 05/16] fix-next: correct raising of layoutChanged event (#6457) Currently the layoutChanged event can be raised even when there is no change due to safe area calculations. --- tns-core-modules/ui/core/view/view.ios.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 0c1a5b15bb..80e74267ba 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -154,7 +154,8 @@ export class View extends ViewCommon { } public _setNativeViewFrame(nativeView: UIView, frame: CGRect): void { - if (!CGRectEqualToRect(nativeView.frame, frame)) { + let oldFrame = this._cachedFrame || nativeView.frame; + if (!CGRectEqualToRect(oldFrame, frame)) { if (traceEnabled()) { traceWrite(this + " :_setNativeViewFrame: " + JSON.stringify(ios.getPositionFromFrame(frame)), traceCategories.Layout); } From b8ca3a4ef89a4a89d9086cc4415446581f1ff492 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Fri, 26 Oct 2018 17:09:19 +0300 Subject: [PATCH 06/16] fix-next(android): restore fade animation for simulated nav (#6463) --- tns-core-modules/ui/frame/frame.android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index bfb911d2cb..d1b7f1f4ac 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -364,7 +364,7 @@ export class Frame extends FrameBase { const newFragmentTag = `fragment${fragmentId}[${navDepth}]`; const newFragment = this.createFragment(newEntry, newFragmentTag); const transaction = manager.beginTransaction(); - const animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false; + const animated = this._getIsAnimatedNavigation(newEntry.entry); // NOTE: Don't use transition for the initial navigation (same as on iOS) // On API 21+ transition won't be triggered unless there was at least one // layout pass so we will wait forever for transitionCompleted handler... From 25df69442fa6d3f2283c72123129d2f0886997c6 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Mon, 29 Oct 2018 19:22:30 +0200 Subject: [PATCH 07/16] fix-next: handle view controller nesting in ng (#6472) --- tns-core-modules/ui/core/view/view.ios.ts | 10 +++++++++- tns-core-modules/ui/page/page.ios.ts | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 80e74267ba..327d748ede 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -889,7 +889,15 @@ export namespace ios { // The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout). const tabViewItem = owner.parent; const tabView = tabViewItem && tabViewItem.parent; - const parent = tabView && tabView.parent; + let parent = tabView && tabView.parent; + + // Handle Angular scenario where TabView is in a ProxyViewContainer + // Not using instanceof ProxyViewContainer to avoid circular dependency + // TODO: Try moving UILayoutViewController out of view module + if (parent && !parent.nativeViewProtected) { + parent = parent.parent; + } + if (parent) { const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top; const currentInsetsTop = this.view.safeAreaInsets.top; diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index 4e737ce361..bf89a2cbc2 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -224,7 +224,15 @@ class UIViewControllerImpl extends UIViewController { // If the Page is nested, cross check safe area insets on top and bottom with Frame parent. const frame = owner.parent; // There is a legacy scenario where Page is not in a Frame - the root of a Modal View, so it has no parent. - const frameParent = frame && frame.parent; + let frameParent = frame && frame.parent; + + // Handle Angular scenario where TabView is in a ProxyViewContainer + // Not using instanceof ProxyViewContainer to avoid circular dependency + // TODO: Try moving UIViewControllerImpl out of page module + if (frameParent && !frameParent.nativeViewProtected) { + frameParent = frameParent.parent; + } + if (frameParent) { const parentPageInsetsTop = frameParent.nativeViewProtected.safeAreaInsets.top; const currentInsetsTop = this.view.safeAreaInsets.top; From 206cc53fd6c90af9fc4d33b1c52e458d4f4697ec Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Mon, 29 Oct 2018 19:43:34 +0200 Subject: [PATCH 08/16] Revert "fix-next(android): restore fade animation for simulated nav (#6463)" (#6473) This reverts commit 448936d6e6bf03c79e17648e8912a4f0eea0b43f. --- tns-core-modules/ui/frame/frame.android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index d1b7f1f4ac..bfb911d2cb 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -364,7 +364,7 @@ export class Frame extends FrameBase { const newFragmentTag = `fragment${fragmentId}[${navDepth}]`; const newFragment = this.createFragment(newEntry, newFragmentTag); const transaction = manager.beginTransaction(); - const animated = this._getIsAnimatedNavigation(newEntry.entry); + const animated = currentEntry ? this._getIsAnimatedNavigation(newEntry.entry) : false; // NOTE: Don't use transition for the initial navigation (same as on iOS) // On API 21+ transition won't be triggered unless there was at least one // layout pass so we will wait forever for transitionCompleted handler... From e20d85f84f49bdcf1706ac7157f50056cfe2a894 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Tue, 30 Oct 2018 14:00:00 +0200 Subject: [PATCH 09/16] fix-next(ios): handle nesting in proxyViewContainer ng (#6475) --- tns-core-modules/ui/core/view/view.ios.ts | 3 ++- tns-core-modules/ui/page/page.ios.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tns-core-modules/ui/core/view/view.ios.ts b/tns-core-modules/ui/core/view/view.ios.ts index 327d748ede..8352f7ae6e 100644 --- a/tns-core-modules/ui/core/view/view.ios.ts +++ b/tns-core-modules/ui/core/view/view.ios.ts @@ -892,9 +892,10 @@ export namespace ios { let parent = tabView && tabView.parent; // Handle Angular scenario where TabView is in a ProxyViewContainer + // It is possible to wrap components in ProxyViewContainers indefinitely // Not using instanceof ProxyViewContainer to avoid circular dependency // TODO: Try moving UILayoutViewController out of view module - if (parent && !parent.nativeViewProtected) { + while (parent && !parent.nativeViewProtected) { parent = parent.parent; } diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index bf89a2cbc2..3ca6fe887e 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -227,9 +227,10 @@ class UIViewControllerImpl extends UIViewController { let frameParent = frame && frame.parent; // Handle Angular scenario where TabView is in a ProxyViewContainer + // It is possible to wrap components in ProxyViewContainers indefinitely // Not using instanceof ProxyViewContainer to avoid circular dependency // TODO: Try moving UIViewControllerImpl out of page module - if (frameParent && !frameParent.nativeViewProtected) { + while (frameParent && !frameParent.nativeViewProtected) { frameParent = frameParent.parent; } From 61bda9ecdfb97c09427640cdce1474f92ce1ef1b Mon Sep 17 00:00:00 2001 From: Alexander Djenkov Date: Tue, 30 Oct 2018 14:24:55 +0200 Subject: [PATCH 10/16] fix(tab-view-android): change androidOffscreenTabLimit to 1 when using bottom tabs (#6476) --- tns-core-modules/ui/tab-view/tab-view.android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/tab-view/tab-view.android.ts b/tns-core-modules/ui/tab-view/tab-view.android.ts index 041b7a7161..18165feb6f 100644 --- a/tns-core-modules/ui/tab-view/tab-view.android.ts +++ b/tns-core-modules/ui/tab-view/tab-view.android.ts @@ -482,7 +482,7 @@ export class TabView extends TabViewBase { public _loadUnloadTabItems(newIndex: number) { const items = this.items; const lastIndex = this.items.length - 1; - const offsideItems = this.androidTabsPosition === "top" ? this.androidOffscreenTabLimit : 0; + const offsideItems = this.androidTabsPosition === "top" ? this.androidOffscreenTabLimit : 1; let toUnload = []; let toLoad = []; From f0f0faf84e098546b706d137e1f9d3a2438f4672 Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Thu, 1 Nov 2018 12:13:47 +0200 Subject: [PATCH 11/16] chore: cut the 5.0.1 release (#6484) --- tns-core-modules/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json index 8e72fa7095..1797a80ea6 100644 --- a/tns-core-modules/package.json +++ b/tns-core-modules/package.json @@ -1,7 +1,7 @@ { "name": "tns-core-modules", "description": "Telerik NativeScript Core Modules", - "version": "5.0.0", + "version": "5.0.1", "homepage": "https://www.nativescript.org", "repository": { "type": "git", From 999e3780ec199f061ef6f9ecca08a4e7337e75de Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Fri, 2 Nov 2018 17:31:52 +0200 Subject: [PATCH 12/16] fix(android): back navigation on app suspend/resume (#6489) --- tns-core-modules/ui/frame/frame.android.ts | 31 +++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index bfb911d2cb..3f98a8ef0b 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -25,10 +25,10 @@ import { createViewFromEntry } from "../builder"; export * from "./frame-common"; interface AnimatorState { - enterAnimator: android.animation.Animator; - exitAnimator: android.animation.Animator; - popEnterAnimator: android.animation.Animator; - popExitAnimator: android.animation.Animator; + enterAnimator: any; + exitAnimator: any; + popEnterAnimator: any; + popExitAnimator: any; transitionName: string; } @@ -306,10 +306,8 @@ export class Frame extends FrameBase { // restore cached animation settings if we just completed simulated first navigation (no animation) if (this._cachedAnimatorState) { restoreAnimatorState(this._currentEntry, this._cachedAnimatorState); - this._cachedAnimatorState = null; } - } public onBackPressed(): boolean { @@ -503,13 +501,26 @@ export class Frame extends FrameBase { } } +function cloneExpandedAnimator(expandedAnimator: any) { + if (!expandedAnimator) { + return null; + } + + const clone = expandedAnimator.clone(); + clone.entry = expandedAnimator.entry; + clone.transitionType = expandedAnimator.transitionType; + + return clone; +} + function getAnimatorState(entry: BackstackEntry): AnimatorState { const expandedEntry = entry; const animatorState = {}; - animatorState.enterAnimator = expandedEntry.enterAnimator; - animatorState.exitAnimator = expandedEntry.exitAnimator; - animatorState.popEnterAnimator = expandedEntry.popEnterAnimator; - animatorState.popExitAnimator = expandedEntry.popExitAnimator; + + animatorState.enterAnimator = cloneExpandedAnimator(expandedEntry.enterAnimator); + animatorState.exitAnimator = cloneExpandedAnimator(expandedEntry.exitAnimator); + animatorState.popEnterAnimator = cloneExpandedAnimator(expandedEntry.popEnterAnimator); + animatorState.popExitAnimator = cloneExpandedAnimator(expandedEntry.popExitAnimator); animatorState.transitionName = expandedEntry.transitionName; return animatorState; From b6a5df18fcd792b094319aaa53540867936f92e7 Mon Sep 17 00:00:00 2001 From: Vasil Chimev Date: Mon, 5 Nov 2018 15:52:34 +0200 Subject: [PATCH 13/16] docs: add 5.0.0 changelog (#6485) * docs: add 5.0.0 changelog * docs: merge 5.0.0 RC and 5.0.0 changelogs --- CHANGELOG.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc93ce4975..76d4473eaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,20 @@ Cross Platform Modules Changelog ============================== - -## [5.0.0 - RC](https://github.com/NativeScript/NativeScript/compare/4.2.1...5.0.0-rc) (2018-10-17) + +# [5.0.0](https://github.com/NativeScript/NativeScript/compare/4.2.1...5.0.0) (2018-11-01) ### Bug Fixes * don't crash on missing resources in tab-view and action-bar ([#6388](https://github.com/NativeScript/NativeScript/issues/6388)) ([56a1b12](https://github.com/NativeScript/NativeScript/commit/56a1b12)) * nested fragments interact through child fragment manager ([#6293](https://github.com/NativeScript/NativeScript/issues/6293)) ([3071720](https://github.com/NativeScript/NativeScript/commit/3071720)) * Page and Frame isLoaded undefined checks ([#6255](https://github.com/NativeScript/NativeScript/issues/6255)) ([12fade7](https://github.com/NativeScript/NativeScript/commit/12fade7)) +* **connectivity:** making startMonitoring() behave on iOS as on Android ([#6373](https://github.com/NativeScript/NativeScript/issues/6373)) ([a58fc52](https://github.com/NativeScript/NativeScript/commit/a58fc52)) +* **observable-array:** reduce no longer ignores zero as initial value ([#6402](https://github.com/NativeScript/NativeScript/issues/6402)) ([c0438df](https://github.com/NativeScript/NativeScript/commit/c0438df)) * **modals:** application activityBackPressed event not fired for modals ([#6261](https://github.com/NativeScript/NativeScript/issues/6261)) ([8575c60](https://github.com/NativeScript/NativeScript/commit/8575c60)) * **list-view:** Layout list-view items on request ([#6159](https://github.com/NativeScript/NativeScript/issues/6159)) ([ec24c5a](https://github.com/NativeScript/NativeScript/commit/ec24c5a)) * **tab-view:** Title and icon positioning ([#6362](https://github.com/NativeScript/NativeScript/issues/6362)) ([e3d5f0d](https://github.com/NativeScript/NativeScript/commit/e3d5f0d)) +* **tab-view:** change androidOffscreenTabLimit to 1 when using bottom tabs for android([#6476](https://github.com/NativeScript/NativeScript/issues/6476)) ([371fc9b](https://github.com/NativeScript/NativeScript/commit/371fc9b)) * **android:** HEAD request should return statusCode ([7e89f94](https://github.com/NativeScript/NativeScript/commit/7e89f94)) * **android:** nested frames on app suspend/resume ([#6339](https://github.com/NativeScript/NativeScript/issues/6339)) ([0bf6dc2](https://github.com/NativeScript/NativeScript/commit/0bf6dc2)) * **android:** parallel navigations should not be triggered ([#6275](https://github.com/NativeScript/NativeScript/issues/6275)) ([6c9fa16](https://github.com/NativeScript/NativeScript/commit/6c9fa16)) @@ -26,6 +29,9 @@ Cross Platform Modules Changelog * add ability to pass touch event through parent view ([#6204](https://github.com/NativeScript/NativeScript/issues/6204)) ([2625683](https://github.com/NativeScript/NativeScript/commit/2625683)) * implement capitalization type option for prompt dialogs ([#6325](https://github.com/NativeScript/NativeScript/issues/6325)) ([ae6a661](https://github.com/NativeScript/NativeScript/commit/ae6a661)) * **application-settings:** implemented allKeys method ([#6371](https://github.com/NativeScript/NativeScript/issues/6371)) ([829d18b](https://github.com/NativeScript/NativeScript/commit/829d18b)) +* **frame:** add new actionBarVisibility property ([#6449](https://github.com/NativeScript/NativeScript/issues/6449)) ([0002624](https://github.com/NativeScript/NativeScript/commit/0002624)) +* **frame:** hardware back in parent frame when back states available ([#6446](https://github.com/NativeScript/NativeScript/issues/6446)) ([af651d6](https://github.com/NativeScript/NativeScript/commit/af651d6)) +* **grid:** implement addChildAtCell ([#6411](https://github.com/NativeScript/NativeScript/issues/6411)) ([a3f1493](https://github.com/NativeScript/NativeScript/commit/a3f1493)) * **image-asset-ios:** add autoScaleFactor option to switch auto scaling ([#6127](https://github.com/NativeScript/NativeScript/issues/6127)) ([81e63ee](https://github.com/NativeScript/NativeScript/commit/81e63ee)) * **styling:** Add two functions to control applicationAdditionalSelectors ([#6124](https://github.com/NativeScript/NativeScript/issues/6124)) ([85b8c01](https://github.com/NativeScript/NativeScript/commit/85b8c01)) * **tslib:** add tslib helpers to global ([#6351](https://github.com/NativeScript/NativeScript/issues/6351)) ([1232d1e](https://github.com/NativeScript/NativeScript/commit/1232d1e)) @@ -87,6 +93,8 @@ export function pageLoaded(args: EventData) { wrapLayout = page.getViewById("wrapLayout"); // or wrapLayout = page.getViewById("wrapLayout"); } ``` +* **android:** change androidOffscreenTabLimit to 1 when using bottom tabs of tab-view([#6476](https://github.com/NativeScript/NativeScript/issues/6476)) ([371fc9b](https://github.com/NativeScript/NativeScript/commit/371fc9b)) + * **ios:** widgets native view lifecycle refactoring - native view is now created right before they are added to visual tree ([#6102](https://github.com/NativeScript/NativeScript/issues/6102)) ([46705ee](https://github.com/NativeScript/NativeScript/commit/46705ee)): The iOS widgets native view lifecycle now matches the Android widgets. Before, the iOS native view was created in the widget constructor and you could manipulate the native view right after the widget is instantiated. After the refactoring, the widget's native view will be created when it's added to the visual tree. The most correct way to manipulate the native view is in the `loaded` event handler. From 7d21b5c9ab1372e5a689c92fde337184b02876dd Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Mon, 5 Nov 2018 16:17:51 +0200 Subject: [PATCH 14/16] fix(android): IllegalStateException with tabview&nested frames (#6495) --- tns-core-modules/ui/frame/frame.android.ts | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index 3f98a8ef0b..81d6cf7fca 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -859,7 +859,38 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks { if (traceEnabled()) { traceWrite(`${fragment}.onDestroy()`, traceCategories.NativeLifecycle); } + superFunc.call(fragment); + + const entry = this.entry; + if (!entry) { + traceError(`${fragment}.onDestroy: entry is null or undefined`); + return null; + } + + const page = entry.resolvedPage; + if (!page) { + traceError(`${fragment}.onDestroy: entry has no resolvedPage`); + return null; + } + + // fixes 'java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first'. + // on app resume in nested frame scenarios with support library version greater than 26.0.0 + // HACK: this whole code block shouldn't be necessary as the native view is supposedly removed from its parent + // right after onDestroyView(...) is called but for some reason the fragment view (page) still thinks it has a + // parent while its supposed parent believes it properly removed its children; in order to "force" the child to + // lose its parent we temporarily add it to the parent, and then remove it (addViewInLayout doesn't trigger layout pass) + const nativeView = page.nativeViewProtected; + if (nativeView != null) { + const parentView = nativeView.getParent(); + if (parentView instanceof android.view.ViewGroup) { + if (parentView.getChildCount() === 0) { + parentView.addViewInLayout(nativeView, -1, new org.nativescript.widgets.CommonLayoutParams()); + } + + parentView.removeView(nativeView); + } + } } @profile From af5eb7321b6d26ce96a124f6d2a993b854d3512d Mon Sep 17 00:00:00 2001 From: Vladimir Amiorkov Date: Fri, 2 Nov 2018 15:33:17 +0200 Subject: [PATCH 15/16] fix: Resolve incorrect name of listener when unsubscribing (#6487) --- tns-core-modules/ui/styling/style-scope.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/styling/style-scope.ts b/tns-core-modules/ui/styling/style-scope.ts index 8e0df7dd14..8f3cf607c9 100644 --- a/tns-core-modules/ui/styling/style-scope.ts +++ b/tns-core-modules/ui/styling/style-scope.ts @@ -506,7 +506,7 @@ export class CssState { this._appliedChangeMap.forEach((changes, view) => { if (changes.attributes) { changes.attributes.forEach(attribute => { - view.removeEventListener("onPropertyChanged:" + attribute, this._onDynamicStateChangeHandler); + view.removeEventListener(attribute + "Change", this._onDynamicStateChangeHandler); }); } if (changes.pseudoClasses) { From ed2e9083e17f754cd680643ea62b42cb7786478b Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Wed, 7 Nov 2018 21:01:05 +0200 Subject: [PATCH 16/16] release: cut the 5.0.2 release (#6522) --- CHANGELOG.md | 12 ++++++++++++ tns-core-modules/package.json | 2 +- tns-platform-declarations/package.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d4473eaf..b6a67121d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ Cross Platform Modules Changelog ============================== + +## [5.0.2](https://github.com/NativeScript/NativeScript/compare/5.0.1...5.0.2) (2018-11-07) + + +### Bug Fixes + +* **android:** back navigation on app suspend/resume ([#6489](https://github.com/NativeScript/NativeScript/issues/6489)) ([999e378](https://github.com/NativeScript/NativeScript/commit/999e378)) +* **android:** IllegalStateException with tabview and nested frames ([#6495](https://github.com/NativeScript/NativeScript/issues/6495)) ([7d21b5c](https://github.com/NativeScript/NativeScript/commit/7d21b5c)) +* Resolve incorrect name of listener when unsubscribing ([#6487](https://github.com/NativeScript/NativeScript/issues/6487)) ([af5eb73](https://github.com/NativeScript/NativeScript/commit/af5eb73)) + + + # [5.0.0](https://github.com/NativeScript/NativeScript/compare/4.2.1...5.0.0) (2018-11-01) diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json index 1797a80ea6..12a93bfefa 100644 --- a/tns-core-modules/package.json +++ b/tns-core-modules/package.json @@ -1,7 +1,7 @@ { "name": "tns-core-modules", "description": "Telerik NativeScript Core Modules", - "version": "5.0.1", + "version": "5.0.2", "homepage": "https://www.nativescript.org", "repository": { "type": "git", diff --git a/tns-platform-declarations/package.json b/tns-platform-declarations/package.json index 2485da6475..3751ce17da 100644 --- a/tns-platform-declarations/package.json +++ b/tns-platform-declarations/package.json @@ -1,6 +1,6 @@ { "name": "tns-platform-declarations", - "version": "5.0.0", + "version": "5.0.2", "description": "Platform-specific TypeScript declarations for NativeScript for accessing native objects", "main": "", "scripts": {