From 03ddb15d1414feaec9fb79b783355fb87872f67e Mon Sep 17 00:00:00 2001 From: Nedyalko Nikolov Date: Wed, 13 May 2015 10:50:37 +0300 Subject: [PATCH] Fixed issue with remaining options menu item (iOS). --- apps/tests/ui/page/page-tests.ios.ts | 39 +++++++++++++++++++ ui/frame/frame-common.ts | 4 -- ui/frame/frame.android.ts | 6 --- ui/frame/frame.d.ts | 1 - ui/frame/frame.ios.ts | 57 +--------------------------- ui/page/page-common.ts | 8 +++- ui/page/page.android.ts | 6 +++ ui/page/page.d.ts | 1 + ui/page/page.ios.ts | 53 ++++++++++++++++++++++++++ 9 files changed, 106 insertions(+), 69 deletions(-) diff --git a/apps/tests/ui/page/page-tests.ios.ts b/apps/tests/ui/page/page-tests.ios.ts index ed5f2c04e..6b2cd32f8 100644 --- a/apps/tests/ui/page/page-tests.ios.ts +++ b/apps/tests/ui/page/page-tests.ios.ts @@ -59,4 +59,43 @@ export function test_NavBar_isVisible_when_MenuItems_areSet() { page.off(view.View.loadedEvent, handler); helper.goBack(); } +} + +export function test_NavBarItemsAreClearedFromNativeWhenClearedFromNativeScript() { + var page: PageModule.Page; + var label: LabelModule.Label; + + var handler = function (data) { + page.off(PageModule.Page.navigatedToEvent, handler); + var menuItems = page.optionsMenu.getItems(); + var i; + for (i = menuItems.length - 1; i >= 0; i--) { + page.optionsMenu.removeItem(menuItems[i]); + } + } + + var pageFactory = function (): PageModule.Page { + page = new PageModule.Page(); + page.on(PageModule.Page.navigatedToEvent, handler); + + var mi = new PageModule.MenuItem(); + mi.text = "B"; + page.optionsMenu.addItem(mi); + label = new LabelModule.Label(); + label.text = "Text"; + page.content = label; + return page; + }; + + helper.navigate(pageFactory); + + try { + var navigationItem: UINavigationItem = ((page.ios).navigationItem); + var rightBarButtonItemsCount = navigationItem.rightBarButtonItems ? navigationItem.rightBarButtonItems.count : 0; + TKUnit.assertEqual(rightBarButtonItemsCount, 0, "After remove all items native items should be 0."); + } + finally { + page.off(view.View.loadedEvent, handler); + helper.goBack(); + } } \ No newline at end of file diff --git a/ui/frame/frame-common.ts b/ui/frame/frame-common.ts index 9e08bdca4..65ed51862 100644 --- a/ui/frame/frame-common.ts +++ b/ui/frame/frame-common.ts @@ -369,10 +369,6 @@ export class Frame extends view.CustomLayoutView implements definition.Frame { public _removeViewFromNativeVisualTree(child: view.View): void { child._isAddedToNativeVisualTree = false; } - - public _invalidateOptionsMenu() { - // - } } var _topmost = function (): Frame { diff --git a/ui/frame/frame.android.ts b/ui/frame/frame.android.ts index d223d0d99..d05af89cb 100644 --- a/ui/frame/frame.android.ts +++ b/ui/frame/frame.android.ts @@ -366,12 +366,6 @@ export class Frame extends frameCommon.Frame { public _clearAndroidReference() { // we should keep the reference to underlying native object, since frame can contain many pages. } - - public _invalidateOptionsMenu() { - if (this.android && this.android.activity) { - this.android.activity.invalidateOptionsMenu(); - } - } } declare module com { diff --git a/ui/frame/frame.d.ts b/ui/frame/frame.d.ts index 3a8c9652a..e22e1d69f 100644 --- a/ui/frame/frame.d.ts +++ b/ui/frame/frame.d.ts @@ -89,7 +89,6 @@ declare module "ui/frame" { //@private _processNavigationQueue(page: pages.Page); - _invalidateOptionsMenu(); //@endprivate /** diff --git a/ui/frame/frame.ios.ts b/ui/frame/frame.ios.ts index 1b84fbdfe..6b8a5c2fc 100644 --- a/ui/frame/frame.ios.ts +++ b/ui/frame/frame.ios.ts @@ -1,7 +1,6 @@ import frameCommon = require("ui/frame/frame-common"); import definition = require("ui/frame"); import trace = require("trace"); -import imageSource = require("image-source"); import pages = require("ui/page"); import enums = require("ui/enums"); import utils = require("utils/utils"); @@ -165,39 +164,6 @@ export class Frame extends frameCommon.Frame { var navigationBar = this._ios.controller.navigationBar; return (navigationBar && !this._ios.controller.navigationBarHidden) ? navigationBar.frame.size.height : 0; } - - public _invalidateOptionsMenu() { - this.populateMenuItems(this.currentPage); - } - - populateMenuItems(page: pages.Page) { - var items = page.optionsMenu.getItems(); - - var navigationItem: UINavigationItem = (page.ios).navigationItem; - var array: NSMutableArray = items.length > 0 ? NSMutableArray.new() : null; - - for (var i = 0; i < items.length; i++) { - var item = items[i]; - var tapHandler = TapBarItemHandlerImpl.new().initWithOwner(item); - // associate handler with menuItem or it will get collected by JSC. - (item).handler = tapHandler; - - var barButtonItem: UIBarButtonItem; - if (item.icon) { - var img = imageSource.fromResource(item.icon); - barButtonItem = UIBarButtonItem.alloc().initWithImageStyleTargetAction(img.ios, UIBarButtonItemStyle.UIBarButtonItemStylePlain, tapHandler, "tap"); - } - else { - barButtonItem = UIBarButtonItem.alloc().initWithTitleStyleTargetAction(item.text, UIBarButtonItemStyle.UIBarButtonItemStylePlain, tapHandler, "tap"); - } - - array.addObject(barButtonItem); - } - - if (array) { - navigationItem.setRightBarButtonItemsAnimated(array, true); - } - } } class UINavigationControllerImpl extends UINavigationController implements UINavigationControllerDelegate { @@ -240,7 +206,7 @@ class UINavigationControllerImpl extends UINavigationController implements UINav } frame._addView(newPage); - frame.populateMenuItems(newPage); + newPage._invalidateOptionsMenu(); } else if (newPage.parent !== frame) { throw new Error("Page is already shown on another frame."); @@ -322,24 +288,3 @@ class iOSFrame implements definition.iOSFrame { this._navBarVisibility = value; } } - -class TapBarItemHandlerImpl extends NSObject { - static new(): TapBarItemHandlerImpl { - return super.new(); - } - - private _owner: pages.MenuItem; - - public initWithOwner(owner: pages.MenuItem): TapBarItemHandlerImpl { - this._owner = owner; - return this; - } - - public tap(args) { - this._owner._raiseTap(); - } - - public static ObjCExposedMethods = { - "tap": { returns: interop.types.void, params: [interop.types.id] } - }; -} \ No newline at end of file diff --git a/ui/page/page-common.ts b/ui/page/page-common.ts index 94564cdd8..16a673caa 100644 --- a/ui/page/page-common.ts +++ b/ui/page/page-common.ts @@ -118,6 +118,10 @@ export class Page extends contentView.ContentView implements dts.Page, view.AddA return this._styleScope; } + public _invalidateOptionsMenu() { + // + } + private _applyCss() { if (this._cssApplied) { return; @@ -217,8 +221,8 @@ export class OptionsMenu implements dts.OptionsMenu { } invalidate() { - if (this._page.frame) { - this._page.frame._invalidateOptionsMenu(); + if (this._page) { + this._page._invalidateOptionsMenu(); } } } diff --git a/ui/page/page.android.ts b/ui/page/page.android.ts index 584bf1344..6209919bc 100644 --- a/ui/page/page.android.ts +++ b/ui/page/page.android.ts @@ -28,4 +28,10 @@ export class Page extends pageCommon.Page { this._isBackNavigation = isBackNavigation; super.onNavigatedFrom(isBackNavigation); } + + public _invalidateOptionsMenu() { + if (this.frame && this.frame.android && this.frame.android.activity) { + this.frame.android.activity.invalidateOptionsMenu(); + } + } } \ No newline at end of file diff --git a/ui/page/page.d.ts b/ui/page/page.d.ts index 9458e688d..1ef972ff4 100644 --- a/ui/page/page.d.ts +++ b/ui/page/page.d.ts @@ -110,6 +110,7 @@ declare module "ui/page" { //@private _getStyleScope(): styleScope.StyleScope; + _invalidateOptionsMenu(); //@endprivate } diff --git a/ui/page/page.ios.ts b/ui/page/page.ios.ts index 98ca8011f..09092ac90 100644 --- a/ui/page/page.ios.ts +++ b/ui/page/page.ios.ts @@ -1,6 +1,7 @@ import pageCommon = require("ui/page/page-common"); import definition = require("ui/page"); import viewModule = require("ui/core/view"); +import imageSource = require("image-source"); import trace = require("trace"); declare var exports; @@ -107,4 +108,56 @@ export class Page extends pageCommon.Page { get _nativeView(): any { return this.ios.view; } + + public _invalidateOptionsMenu() { + this.populateMenuItems(); + } + + populateMenuItems() { + var items = this.optionsMenu.getItems(); + + var navigationItem: UINavigationItem = (this.ios).navigationItem; + var array: NSMutableArray = items.length > 0 ? NSMutableArray.new() : null; + + for (var i = 0; i < items.length; i++) { + var item = items[i]; + var tapHandler = TapBarItemHandlerImpl.new().initWithOwner(item); + // associate handler with menuItem or it will get collected by JSC. + (item).handler = tapHandler; + + var barButtonItem: UIBarButtonItem; + if (item.icon) { + var img = imageSource.fromResource(item.icon); + barButtonItem = UIBarButtonItem.alloc().initWithImageStyleTargetAction(img.ios, UIBarButtonItemStyle.UIBarButtonItemStylePlain, tapHandler, "tap"); + } + else { + barButtonItem = UIBarButtonItem.alloc().initWithTitleStyleTargetAction(item.text, UIBarButtonItemStyle.UIBarButtonItemStylePlain, tapHandler, "tap"); + } + + array.addObject(barButtonItem); + } + + navigationItem.setRightBarButtonItemsAnimated(array, true); + } +} + +class TapBarItemHandlerImpl extends NSObject { + static new(): TapBarItemHandlerImpl { + return super.new(); + } + + private _owner: definition.MenuItem; + + public initWithOwner(owner: definition.MenuItem): TapBarItemHandlerImpl { + this._owner = owner; + return this; + } + + public tap(args) { + this._owner._raiseTap(); + } + + public static ObjCExposedMethods = { + "tap": { returns: interop.types.void, params: [interop.types.id] } + }; } \ No newline at end of file