diff --git a/Examples/UIExplorer/NavigatorIOSExample.js b/Examples/UIExplorer/NavigatorIOSExample.js index 4a2011a654611c..64f36996a4de69 100644 --- a/Examples/UIExplorer/NavigatorIOSExample.js +++ b/Examples/UIExplorer/NavigatorIOSExample.js @@ -48,7 +48,7 @@ var NavigatorIOSExample = React.createClass({ title: '', description: 'iOS navigation capabilities', }, - + counter:10, render: function() { var recurseTitle = 'Recurse Navigation'; if (!this.props.topExampleRoute) { @@ -82,6 +82,17 @@ var NavigatorIOSExample = React.createClass({ component: createExamplePage(null, ViewExample), }); })} + {this._renderRow('Change rightButtonTitle', () => { + this.props.navigator.updateNavBar({rightButtonTitle:this.counter++,onRightButtonPress:()=>{ + this.counter = 10; + this.props.navigator.updateNavBar({rightButtonTitle:null}); + }}); + })} + {this._renderRow('Transparant navBar', () => { + this.props.navigator.updateNavBar({rightButtonTitle:"Reset",navigationBarTransparent:true,onRightButtonPress:()=>{ + this.props.navigator.updateNavBar({navigationBarTransparent:false,rightButtonTitle:null,onRightButtonPress:null}); + }}); + })} {this._renderRow('Custom Right Button', () => { this.props.navigator.push({ title: NavigatorIOSExample.title, diff --git a/Libraries/Components/Navigation/NavigatorIOS.ios.js b/Libraries/Components/Navigation/NavigatorIOS.ios.js index 053ab0ee38f9b5..24d7a3a102353e 100644 --- a/Libraries/Components/Navigation/NavigatorIOS.ios.js +++ b/Libraries/Components/Navigation/NavigatorIOS.ios.js @@ -60,6 +60,7 @@ var RCTNavigatorItem = createReactNativeComponentClass({ tintColor: true, translucent: true, navigationBarHidden: true, + navigationBarTransparent: true, titleTextColor: true, style: true, }, @@ -94,6 +95,8 @@ type Route = { rightButtonTitle?: string; rightButtonIcon?: Object; onRightButtonPress?: Function; + navigationBarHidden?: Boolean; + navigationBarTransparent?: Boolean; wrapperStyle?: any; }; @@ -106,6 +109,7 @@ type State = { fromIndex: number; toIndex: number; makingNavigatorRequest: boolean; + navBarReload: boolean; updatingAllIndicesAtOrBeyond: number; } @@ -281,6 +285,11 @@ var NavigatorIOS = React.createClass({ */ navigationBarHidden: PropTypes.bool, + /** + * A Boolean value that indicates whether the navigation bar is totaly transparent + */ + navigationBarTransparent: PropTypes.bool, + /** * The default wrapper style for components in the navigator. * A common use case is to set the backgroundColor for every page @@ -316,6 +325,7 @@ var NavigatorIOS = React.createClass({ // Precompute a pack of callbacks that's frequently generated and passed to // instances. this.navigator = { + updateNavBar:this.updateNavBar, push: this.push, pop: this.pop, popN: this.popN, @@ -339,6 +349,17 @@ var NavigatorIOS = React.createClass({ this.navigationContext = new NavigationContext(); }, + updateNavBar: function (route: Route){ + if (route !== undefined){ + var current: Route = this.state.routeStack[this.state.routeStack.length - 1] ; + this.state.routeStack[this.state.routeStack.length - 1] = merge(current, route); + } + + this.setState({ + navBarReload:true, + makingNavigatorRequest: true, + }); + }, getInitialState: function(): State { return { idStack: [getuid()], @@ -358,6 +379,7 @@ var NavigatorIOS = React.createClass({ // Whether or not we are making a navigator request to push/pop. (Used // for performance optimization). makingNavigatorRequest: false, + navBarReload: false, // Whether or not we are updating children of navigator and if so (not // `null`) which index marks the beginning of all updates. Used for // performance optimization. @@ -620,8 +642,10 @@ var NavigatorIOS = React.createClass({ _routeToStackItem: function(route: Route, i: number) { var Component = route.component; var shouldUpdateChild = this.state.updatingAllIndicesAtOrBeyond !== null && - this.state.updatingAllIndicesAtOrBeyond >= i; - + this.state.updatingAllIndicesAtOrBeyond >= i || this.state.navBarReload; + var navigationBarHidden = route.navigationBarHidden !== undefined ? route.navigationBarHidden : this.props.navigationBarHidden; + var navigationBarTransparent = route.navigationBarTransparent !== undefined ? route.navigationBarTransparent : this.props.navigationBarTransparent; + return ( +@class RCTNavItem; + +@protocol RCTNavItemListener + +-(void)update:(RCTNavItem *)itemNav; + +@end + @interface RCTNavItem : UIView @property (nonatomic, copy) NSString *title; @@ -19,6 +27,7 @@ @property (nonatomic, strong) UIImage *backButtonIcon; @property (nonatomic, copy) NSString *backButtonTitle; @property (nonatomic, assign) BOOL navigationBarHidden; +@property (nonatomic, assign) BOOL navigationBarTransparent; @property (nonatomic, strong) UIColor *tintColor; @property (nonatomic, strong) UIColor *barTintColor; @property (nonatomic, strong) UIColor *titleTextColor; @@ -28,4 +37,6 @@ @property (nonatomic, readonly) UIBarButtonItem *leftButtonItem; @property (nonatomic, readonly) UIBarButtonItem *rightButtonItem; +@property (nonatomic, weak) id delegate; + @end diff --git a/React/Views/RCTNavItem.m b/React/Views/RCTNavItem.m index f875e6aa55777d..4de03f8d0bc011 100644 --- a/React/Views/RCTNavItem.m +++ b/React/Views/RCTNavItem.m @@ -14,6 +14,12 @@ @implementation RCTNavItem @synthesize backButtonItem = _backButtonItem; @synthesize leftButtonItem = _leftButtonItem; @synthesize rightButtonItem = _rightButtonItem; +@synthesize navigationBarTransparent = _navigationBarTransparent; + +- (void)setNavigationBarTransparent:(BOOL)transparent{ + _navigationBarTransparent = transparent; + [self.delegate update:self]; +} - (void)setBackButtonTitle:(NSString *)backButtonTitle { @@ -25,6 +31,7 @@ - (void)setBackButtonIcon:(UIImage *)backButtonIcon { _backButtonIcon = backButtonIcon; _backButtonItem = nil; + [self.delegate update:self]; } - (UIBarButtonItem *)backButtonItem @@ -51,12 +58,14 @@ - (void)setLeftButtonTitle:(NSString *)leftButtonTitle { _leftButtonTitle = leftButtonTitle; _leftButtonItem = nil; + [self.delegate update:self]; } - (void)setLeftButtonIcon:(UIImage *)leftButtonIcon { _leftButtonIcon = leftButtonIcon; _leftButtonItem = nil; + [self.delegate update:self]; } - (UIBarButtonItem *)leftButtonItem @@ -83,12 +92,14 @@ - (void)setRightButtonTitle:(NSString *)rightButtonTitle { _rightButtonTitle = rightButtonTitle; _rightButtonItem = nil; + [self.delegate update:self]; } - (void)setRightButtonIcon:(UIImage *)rightButtonIcon { _rightButtonIcon = rightButtonIcon; _rightButtonItem = nil; + [self.delegate update:self]; } - (UIBarButtonItem *)rightButtonItem diff --git a/React/Views/RCTNavItemManager.m b/React/Views/RCTNavItemManager.m index dab6ee049a86b7..9f1973fe2455f2 100644 --- a/React/Views/RCTNavItemManager.m +++ b/React/Views/RCTNavItemManager.m @@ -22,6 +22,7 @@ - (UIView *)view } RCT_EXPORT_VIEW_PROPERTY(navigationBarHidden, BOOL) +RCT_EXPORT_VIEW_PROPERTY(navigationBarTransparent, BOOL) RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(barTintColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL) diff --git a/React/Views/RCTWrapperViewController.h b/React/Views/RCTWrapperViewController.h index 09e64789170359..93377b60d530f9 100644 --- a/React/Views/RCTWrapperViewController.h +++ b/React/Views/RCTWrapperViewController.h @@ -10,11 +10,13 @@ #import #import "RCTViewControllerProtocol.h" +#import "RCTNavItem.h" @class RCTEventDispatcher; @class RCTNavItem; @class RCTWrapperViewController; + @protocol RCTWrapperViewControllerNavigationListener - (void)wrapperViewController:(RCTWrapperViewController *)wrapperViewController @@ -22,7 +24,9 @@ didMoveToNavigationController:(UINavigationController *)navigationController; @end -@interface RCTWrapperViewController : UIViewController + + +@interface RCTWrapperViewController : UIViewController - (instancetype)initWithContentView:(UIView *)contentView eventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER; @@ -33,4 +37,5 @@ didMoveToNavigationController:(UINavigationController *)navigationController; @property (nonatomic, weak) id navigationListener; @property (nonatomic, strong) RCTNavItem *navItem; + @end diff --git a/React/Views/RCTWrapperViewController.m b/React/Views/RCTWrapperViewController.m index c1893353b17d43..93566caf444723 100644 --- a/React/Views/RCTWrapperViewController.m +++ b/React/Views/RCTWrapperViewController.m @@ -24,6 +24,7 @@ @implementation RCTWrapperViewController RCTEventDispatcher *_eventDispatcher; CGFloat _previousTopLayout; CGFloat _previousBottomLayout; + BOOL translusante; } @synthesize currentTopLayoutGuide = _currentTopLayoutGuide; @@ -63,6 +64,10 @@ - (void)viewWillLayoutSubviews _currentBottomLayoutGuide = self.bottomLayoutGuide; } +-(void)viewDidLoad{ + [super viewDidLoad]; + translusante = self.navigationController.navigationBar.translucent; +} - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; @@ -77,29 +82,54 @@ - (void)viewWillAppear:(BOOL)animated if (!_navItem) { return; } - - UINavigationBar *bar = self.navigationController.navigationBar; - bar.barTintColor = _navItem.barTintColor; - bar.tintColor = _navItem.tintColor; - bar.translucent = _navItem.translucent; - if (_navItem.titleTextColor) { - [bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}]; - } - - UINavigationItem *item = self.navigationItem; - item.title = _navItem.title; - item.backBarButtonItem = _navItem.backButtonItem; - if ((item.leftBarButtonItem = _navItem.leftButtonItem)) { - item.leftBarButtonItem.target = self; - item.leftBarButtonItem.action = @selector(handleNavLeftButtonTapped); - } - if ((item.rightBarButtonItem = _navItem.rightButtonItem)) { - item.rightBarButtonItem.target = self; - item.rightBarButtonItem.action = @selector(handleNavRightButtonTapped); - } + [self update:_navItem animated:animated]; + } +} +-(void)update:(RCTNavItem *)navItem { + [self update:navItem animated:NO]; +} +-(void)update:(RCTNavItem *)navItem animated:(BOOL)animated{ + if (!_navItem) { + return; + } + + if (_navItem.navigationBarTransparent) { + [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; + [self.navigationController.navigationBar setTranslucent:YES]; + [self.navigationController.navigationBar setShadowImage:[UIImage new]]; + }else{ + [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; + [self.navigationController.navigationBar setTranslucent:translusante]; + [self.navigationController.navigationBar setShadowImage:nil]; + } + + [self.navigationController + setNavigationBarHidden:_navItem.navigationBarHidden + animated:animated]; + + + _navItem = navItem; + _navItem.delegate = self; + + UINavigationBar *bar = self.navigationController.navigationBar; + bar.barTintColor = _navItem.barTintColor; + bar.tintColor = _navItem.tintColor; + if (_navItem.titleTextColor) { + [bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}]; + } + + UINavigationItem *item = self.navigationItem; + item.title = _navItem.title; + item.backBarButtonItem = _navItem.backButtonItem; + if ((item.leftBarButtonItem = _navItem.leftButtonItem)) { + item.leftBarButtonItem.target = self; + item.leftBarButtonItem.action = @selector(handleNavLeftButtonTapped); + } + if ((item.rightBarButtonItem = _navItem.rightButtonItem)) { + item.rightBarButtonItem.target = self; + item.rightBarButtonItem.action = @selector(handleNavRightButtonTapped); } } - - (void)loadView { // Add a wrapper so that the wrapper view managed by the