diff --git a/Examples/UIExplorer/js/NavigatorIOSExample.js b/Examples/UIExplorer/js/NavigatorIOSExample.js index 09c569f4160..e84f6a49ab1 100644 --- a/Examples/UIExplorer/js/NavigatorIOSExample.js +++ b/Examples/UIExplorer/js/NavigatorIOSExample.js @@ -90,6 +90,17 @@ class NavigatorIOSExamplePage extends React.Component { } }); })} + {this._renderRow('Custom Right System Button', () => { + this.props.navigator.push({ + title: NavigatorIOSExample.title, + component: EmptyPage, + rightButtonSystemIcon: 'bookmarks', + onRightButtonPress: () => this.props.navigator.pop(), + passProps: { + text: 'This page has a right system button in the nav bar', + } + }); + })} {this._renderRow('Custom Left & Right Icons', () => { this.props.navigator.push({ title: NavigatorIOSExample.title, @@ -114,6 +125,30 @@ class NavigatorIOSExamplePage extends React.Component { } }); })} + {this._renderRow('Custom Left & Right System Icons', () => { + this.props.navigator.push({ + title: NavigatorIOSExample.title, + component: EmptyPage, + leftButtonSystemIcon: 'cancel', + onLeftButtonPress: () => this.props.navigator.pop(), + rightButtonSystemIcon: 'search', + onRightButtonPress: () => { + AlertIOS.alert( + 'Bar Button Action', + 'Recognized a tap on the bar button icon', + [ + { + text: 'OK', + onPress: () => console.log('Tapped OK'), + }, + ] + ); + }, + passProps: { + text: 'This page has an icon for the right button in the nav bar', + } + }); + })} {this._renderRow('Pop', () => { this.props.navigator.pop(); })} diff --git a/Libraries/Components/Navigation/NavigatorIOS.ios.js b/Libraries/Components/Navigation/NavigatorIOS.ios.js index 922bfde8cf9..2ec479b7113 100644 --- a/Libraries/Components/Navigation/NavigatorIOS.ios.js +++ b/Libraries/Components/Navigation/NavigatorIOS.ios.js @@ -25,6 +25,8 @@ var invariant = require('fbjs/lib/invariant'); var logError = require('logError'); var requireNativeComponent = require('requireNativeComponent'); +const keyMirror = require('fbjs/lib/keyMirror'); + var TRANSITIONER_REF = 'transitionerRef'; var PropTypes = React.PropTypes; @@ -50,6 +52,34 @@ class NavigatorTransitionerIOS extends React.Component { } } +const SystemIconLabels = { + done: true, + cancel: true, + edit: true, + save: true, + add: true, + compose: true, + reply: true, + action: true, + organize: true, + bookmarks: true, + search: true, + refresh: true, + stop: true, + camera: true, + trash: true, + play: true, + pause: true, + rewind: true, + 'fast-forward': true, + undo: true, + redo: true, + 'page-curl': true, +}; +const SystemIcons = keyMirror(SystemIconLabels); + +type SystemButtonType = $Enum; + type Route = { component: Function, title: string, @@ -59,9 +89,11 @@ type Route = { backButtonIcon?: Object, leftButtonTitle?: string, leftButtonIcon?: Object, + leftButtonSystemIcon?: SystemButtonType; onLeftButtonPress?: Function, rightButtonTitle?: string, rightButtonIcon?: Object, + rightButtonSystemIcon?: SystemButtonType; onRightButtonPress?: Function, wrapperStyle?: any, }; @@ -336,6 +368,16 @@ var NavigatorIOS = React.createClass({ */ leftButtonTitle: PropTypes.string, + /** + * If set, the left header button will appear with this system icon + * + * Supported icons are `done`, `cancel`, `edit`, `save`, `add`, + * `compose`, `reply`, `action`, `organize`, `bookmarks`, `search`, + * `refresh`, `stop`, `camera`, `trash`, `play`, `pause`, `rewind`, + * `fast-forward`, `undo`, `redo`, and `page-curl` + */ + leftButtonSystemIcon: PropTypes.oneOf(Object.keys(SystemIcons)), + /** * This function will be invoked when the left navigation bar item is * pressed. @@ -353,6 +395,13 @@ var NavigatorIOS = React.createClass({ */ rightButtonTitle: PropTypes.string, + /** + * If set, the right header button will appear with this system icon + * + * See leftButtonSystemIcon for supported icons + */ + rightButtonSystemIcon: PropTypes.oneOf(Object.keys(SystemIcons)), + /** * This function will be invoked when the right navigation bar item is * pressed. diff --git a/React/Views/RCTNavItem.h b/React/Views/RCTNavItem.h index 29c7ff73b40..0d457933f4c 100644 --- a/React/Views/RCTNavItem.h +++ b/React/Views/RCTNavItem.h @@ -17,8 +17,10 @@ @property (nonatomic, strong) UIImage *titleImage; @property (nonatomic, strong) UIImage *leftButtonIcon; @property (nonatomic, copy) NSString *leftButtonTitle; +@property (nonatomic, assign) UIBarButtonSystemItem leftButtonSystemIcon; @property (nonatomic, strong) UIImage *rightButtonIcon; @property (nonatomic, copy) NSString *rightButtonTitle; +@property (nonatomic, assign) UIBarButtonSystemItem rightButtonSystemIcon; @property (nonatomic, strong) UIImage *backButtonIcon; @property (nonatomic, copy) NSString *backButtonTitle; @property (nonatomic, assign) BOOL navigationBarHidden; diff --git a/React/Views/RCTNavItem.m b/React/Views/RCTNavItem.m index 41cb88a16ac..1b47128d1a1 100644 --- a/React/Views/RCTNavItem.m +++ b/React/Views/RCTNavItem.m @@ -24,6 +24,15 @@ } } +-(instancetype)init +{ + if (self = [super init]) { + _leftButtonSystemIcon = NSNotFound; + _rightButtonSystemIcon = NSNotFound; + } + return self; +} + - (void)setBackButtonTitle:(NSString *)backButtonTitle { _backButtonTitle = backButtonTitle; @@ -68,6 +77,12 @@ _leftButtonItem = nil; } +- (void)setLeftButtonSystemIcon:(UIBarButtonSystemItem)leftButtonSystemIcon +{ + _leftButtonSystemIcon = leftButtonSystemIcon; + _leftButtonItem = nil; +} + - (UIBarButtonItem *)leftButtonItem { if (!_leftButtonItem) { @@ -84,6 +99,12 @@ style:UIBarButtonItemStylePlain target:self action:@selector(handleLeftButtonPress)]; + + } else if (_leftButtonSystemIcon != NSNotFound) { + _leftButtonItem = + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:_leftButtonSystemIcon + target:self + action:@selector(handleLeftButtonPress)]; } else { _leftButtonItem = nil; } @@ -110,6 +131,12 @@ _rightButtonItem = nil; } +- (void)setRightButtonSystemIcon:(UIBarButtonSystemItem)rightButtonSystemIcon +{ + _rightButtonSystemIcon = rightButtonSystemIcon; + _rightButtonItem = nil; +} + - (UIBarButtonItem *)rightButtonItem { if (!_rightButtonItem) { @@ -126,6 +153,12 @@ style:UIBarButtonItemStylePlain target:self action:@selector(handleRightButtonPress)]; + + } else if (_rightButtonSystemIcon != NSNotFound) { + _rightButtonItem = + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:_rightButtonSystemIcon + target:self + action:@selector(handleRightButtonPress)]; } else { _rightButtonItem = nil; } diff --git a/React/Views/RCTNavItemManager.h b/React/Views/RCTNavItemManager.h index 309cc89ccd3..5d6f97b1126 100644 --- a/React/Views/RCTNavItemManager.h +++ b/React/Views/RCTNavItemManager.h @@ -9,7 +9,14 @@ #import "RCTViewManager.h" -@interface RCTNavItemManager : RCTViewManager +#import "RCTConvert.h" + +@interface RCTConvert (BarButtonSystemItem) + ++ (UIBarButtonSystemItem)UIBarButtonSystemItem:(id)json; @end +@interface RCTNavItemManager : RCTViewManager + +@end diff --git a/React/Views/RCTNavItemManager.m b/React/Views/RCTNavItemManager.m index 3fa4f6d5838..bb71c47d4a5 100644 --- a/React/Views/RCTNavItemManager.m +++ b/React/Views/RCTNavItemManager.m @@ -12,6 +12,37 @@ #import "RCTConvert.h" #import "RCTNavItem.h" +@implementation RCTConvert (BarButtonSystemItem) + +RCT_ENUM_CONVERTER(UIBarButtonSystemItem, (@{ + @"done": @(UIBarButtonSystemItemDone), + @"cancel": @(UIBarButtonSystemItemCancel), + @"edit": @(UIBarButtonSystemItemEdit), + @"save": @(UIBarButtonSystemItemSave), + @"add": @(UIBarButtonSystemItemAdd), + @"flexible-space": @(UIBarButtonSystemItemFlexibleSpace), + @"fixed-space": @(UIBarButtonSystemItemFixedSpace), + @"compose": @(UIBarButtonSystemItemCompose), + @"reply": @(UIBarButtonSystemItemReply), + @"action": @(UIBarButtonSystemItemAction), + @"organize": @(UIBarButtonSystemItemOrganize), + @"bookmarks": @(UIBarButtonSystemItemBookmarks), + @"search": @(UIBarButtonSystemItemSearch), + @"refresh": @(UIBarButtonSystemItemRefresh), + @"stop": @(UIBarButtonSystemItemStop), + @"camera": @(UIBarButtonSystemItemCamera), + @"trash": @(UIBarButtonSystemItemTrash), + @"play": @(UIBarButtonSystemItemPlay), + @"pause": @(UIBarButtonSystemItemPause), + @"rewind": @(UIBarButtonSystemItemRewind), + @"fast-forward": @(UIBarButtonSystemItemFastForward), + @"undo": @(UIBarButtonSystemItemUndo), + @"redo": @(UIBarButtonSystemItemRedo), + @"page-curl": @(UIBarButtonSystemItemPageCurl) +}), NSNotFound, integerValue); + +@end + @implementation RCTNavItemManager RCT_EXPORT_MODULE() @@ -36,9 +67,11 @@ RCT_EXPORT_VIEW_PROPERTY(backButtonTitle, NSString) RCT_EXPORT_VIEW_PROPERTY(leftButtonTitle, NSString) RCT_EXPORT_VIEW_PROPERTY(leftButtonIcon, UIImage) +RCT_EXPORT_VIEW_PROPERTY(leftButtonSystemIcon, UIBarButtonSystemItem) RCT_EXPORT_VIEW_PROPERTY(rightButtonIcon, UIImage) RCT_EXPORT_VIEW_PROPERTY(rightButtonTitle, NSString) +RCT_EXPORT_VIEW_PROPERTY(rightButtonSystemIcon, UIBarButtonSystemItem) RCT_EXPORT_VIEW_PROPERTY(onLeftButtonPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRightButtonPress, RCTBubblingEventBlock)