Merge pull request #156 from NativeScript/nnikolov/RemainingOptionsMenuItemIos

Fixed issue with remaining options menu item (iOS).
This commit is contained in:
Nedyalko Nikolov
2015-05-13 12:25:44 +03:00
9 changed files with 106 additions and 69 deletions

View File

@ -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 = ((<UIViewController>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();
}
}

View File

@ -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 {

View File

@ -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 {

1
ui/frame/frame.d.ts vendored
View File

@ -89,7 +89,6 @@ declare module "ui/frame" {
//@private
_processNavigationQueue(page: pages.Page);
_invalidateOptionsMenu();
//@endprivate
/**

View File

@ -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 = (<UIViewController>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.
(<any>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 <TapBarItemHandlerImpl>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] }
};
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

1
ui/page/page.d.ts vendored
View File

@ -110,6 +110,7 @@ declare module "ui/page" {
//@private
_getStyleScope(): styleScope.StyleScope;
_invalidateOptionsMenu();
//@endprivate
}

View File

@ -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 = (<UIViewController>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.
(<any>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 <TapBarItemHandlerImpl>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] }
};
}