2015-03-23 22:07:33 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
2015-03-06 17:54:10 +00:00
|
|
|
|
|
|
|
#import "RCTTabBar.h"
|
|
|
|
|
|
|
|
#import "RCTEventDispatcher.h"
|
|
|
|
#import "RCTLog.h"
|
|
|
|
#import "RCTTabBarItem.h"
|
|
|
|
#import "RCTUtils.h"
|
|
|
|
#import "RCTView.h"
|
|
|
|
#import "RCTViewControllerProtocol.h"
|
|
|
|
#import "RCTWrapperViewController.h"
|
2015-03-26 13:32:01 +00:00
|
|
|
#import "UIView+React.h"
|
2015-03-06 17:54:10 +00:00
|
|
|
|
|
|
|
@interface RKCustomTabBarController : UITabBarController <RCTViewControllerProtocol>
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RKCustomTabBarController
|
|
|
|
|
|
|
|
@synthesize currentTopLayoutGuide = _currentTopLayoutGuide;
|
|
|
|
@synthesize currentBottomLayoutGuide = _currentBottomLayoutGuide;
|
|
|
|
|
|
|
|
- (void)viewWillLayoutSubviews
|
|
|
|
{
|
|
|
|
[super viewWillLayoutSubviews];
|
|
|
|
_currentTopLayoutGuide = self.topLayoutGuide;
|
|
|
|
_currentBottomLayoutGuide = self.bottomLayoutGuide;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface RCTTabBar() <UITabBarControllerDelegate>
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTTabBar
|
|
|
|
{
|
|
|
|
BOOL _tabsChanged;
|
|
|
|
RCTEventDispatcher *_eventDispatcher;
|
|
|
|
UITabBarController *_tabController;
|
|
|
|
NSMutableArray *_tabViews;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
|
|
|
{
|
|
|
|
if ((self = [super initWithFrame:CGRectZero])) {
|
|
|
|
_eventDispatcher = eventDispatcher;
|
|
|
|
_tabViews = [[NSMutableArray alloc] init];
|
|
|
|
_tabController = [[RKCustomTabBarController alloc] init];
|
|
|
|
_tabController.delegate = self;
|
|
|
|
[self addSubview:_tabController.view];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (UIViewController *)backingViewController
|
|
|
|
{
|
|
|
|
return _tabController;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
_tabController.delegate = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *)reactSubviews
|
|
|
|
{
|
|
|
|
return _tabViews;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
|
|
|
|
{
|
|
|
|
if (![view isKindOfClass:[RCTTabBarItem class]]) {
|
|
|
|
RCTLogError(@"subview should be of type RCTTabBarItem");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
[_tabViews insertObject:view atIndex:atIndex];
|
|
|
|
_tabsChanged = YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)removeReactSubview:(UIView *)subview
|
|
|
|
{
|
|
|
|
if (_tabViews.count == 0) {
|
|
|
|
RCTLogError(@"should have at least one view to remove a subview");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
[_tabViews removeObject:subview];
|
|
|
|
_tabsChanged = YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)layoutSubviews
|
|
|
|
{
|
|
|
|
[super layoutSubviews];
|
|
|
|
_tabController.view.frame = self.bounds;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)reactBridgeDidFinishTransaction
|
|
|
|
{
|
|
|
|
// we can't hook up the VC hierarchy in 'init' because the subviews aren't
|
|
|
|
// hooked up yet, so we do it on demand here whenever a transaction has finished
|
|
|
|
[self addControllerToClosestParent:_tabController];
|
|
|
|
|
|
|
|
if (_tabsChanged) {
|
|
|
|
|
|
|
|
NSMutableArray *viewControllers = [NSMutableArray array];
|
|
|
|
for (RCTTabBarItem *tab in [self reactSubviews]) {
|
|
|
|
UIViewController *controller = tab.backingViewController;
|
|
|
|
if (!controller) {
|
|
|
|
controller = [[RCTWrapperViewController alloc] initWithContentView:tab
|
|
|
|
eventDispatcher:_eventDispatcher];
|
|
|
|
}
|
|
|
|
[viewControllers addObject:controller];
|
|
|
|
}
|
|
|
|
|
|
|
|
_tabController.viewControllers = viewControllers;
|
|
|
|
_tabsChanged = NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[self reactSubviews] enumerateObjectsUsingBlock:^(RCTTabBarItem *tab, NSUInteger index, BOOL *stop) {
|
|
|
|
UIViewController *controller = _tabController.viewControllers[index];
|
|
|
|
controller.tabBarItem = tab.barItem;
|
|
|
|
if (tab.selected) {
|
|
|
|
_tabController.selectedViewController = controller;
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - UITabBarControllerDelegate
|
|
|
|
|
|
|
|
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
|
|
|
|
{
|
|
|
|
NSUInteger index = [tabBarController.viewControllers indexOfObject:viewController];
|
|
|
|
RCTTabBarItem *tab = [self reactSubviews][index];
|
|
|
|
[_eventDispatcher sendInputEventWithName:@"topTap" body:@{@"target": tab.reactTag}];
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|