Reputation: 27214
I have a tabBarController
that I add by placing the following code into:
AppDelegate.h:
...
UITabBarController IBOutlet *tabBarController;
}
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
AppDelegate.m:
...
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
[tabBarController setDelegate:self];
I then use the following code to present a modal barcode scanning View Controller:
- (void)tabBarController:(UITabBarController *)tbc didSelectViewController:(UIViewController *)vc {
// Middle tab bar item in question.
if (vc == [tabBarController.viewControllers objectAtIndex:2]) {
ScanVC *scanView = [[ScanVC alloc] initWithNibName:@"ScanViewController" bundle:nil];
// set properties of scanView's ivars, etc
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:scanView];
[tabBarController presentModalViewController:navigationController animated:YES];
[navigationController release];
[scanView release];
}
}
When it does actually get presented I think this method isn't visually appealing, because when I dismiss the modal view I am brought back to an empty view.
A lot of barcode scanning applications or applications that simply display an image picker for example; do this quite successfully. I'm just wondering what kind of implementation they would use in order to achieve such an effect.
This is a screenshot of an application called Path, which has the exact same functionality I'm after:
I also noticed that in these applications, if you are on any other tab bar item other than the middle one let's say, and you click on the tab bar item that presents the modal view, once it gets dismissed it doesn't actually bring them back to an empty view it dismisses like normal, however the actual tab bar item that presents the modal view is never selected. I would be happy with this type of functionality if that's the only way to implement this type of effect.
Any help would be greatly appreciated as I've been stuck in this for quite some time. Also I'm not even sure whether it's the right way to put all of this code in my AppDelegate
in order for the View Controller to be presented as a modal. It all seems, just, wrong.
Upvotes: 7
Views: 5756
Reputation: 13511
I found a really easy solution by playing around UITabBarControllerDelegate
--I only tried this in iOS 7 though.
First, subclass UITabBarController
, make it its own UITabBarControllerDelegate
, and create a property that'll hold a reference to the tab you want to launch a modal with. In my app, it's called the "Sell" tab.
@property (strong, nonatomic) UIViewController *sellTab;
Then, in your init
method, just create that view controller and add it to the tabs.
_sellTab = [[UIViewController alloc] init];
_sellTab.title = @"Sell";
self.viewControllers = @[homeTab, historyTab, _sellTab, bookmarksTab, profileTab];
Now here's where the magic is: override the following tab bar controller delegate methods. Code is pretty self-explanatory.
#pragma mark - Tab bar controller delegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
return viewController != self.sellTab;
}
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
if (item == self.sellTab.tabBarItem) {
[self presentViewController:[[UINavigationController alloc] initWithRootViewController:[[PostAdViewController alloc] init]] animated:YES completion:nil];
}
}
This will launch a modal which, upon dismissal, shows the same tab you were in before launch.
Upvotes: 2
Reputation: 113747
When you dismiss the modal view controller, tell the tab bar to select whatever tab was originally selected.
- (void)dismissModalViewControllerAnimated:(BOOL)animated
{
// do whatever you need to do when dismissing
// savedTabIndex is an int ivar
// tabBarController is a reference, set when showing the modal view
[[self tabBarController] setSelectedIndex:savedTabIndex];
}
You would have to save the original tab bar selection in a variable at the start of tabBarController:didSelectViewController:
.
- (void)tabBarController:(UITabBarController *)tbc
didSelectViewController:(UIViewController *)vc
{
// Save the tab bar index (if it's not the photo tab)
if ([tabBarController selectedIndex] != 3]) {
savedTabIndex = [tabBarController selectedIndex];
}
}
There could be mistakes in this code, I just typed it without testing.
Upvotes: 2
Reputation: 27214
Not entirely what I'm after, but I think I can move forward from this:
http://idevrecipes.com/2010/12/16/raised-center-tab-bar-button/
Upvotes: 2
Reputation: 458
You shouldn't present a modal view, when the user clicks on a tab bar item.
You could instead present a modal view from within a view that's presented by one of the tabs.
Or, if you just have a single main view and the scan view you want to present modally, you should just use a button to present the scan view from within your main view. You could for instance use a toolbar with a single button in it, instead.
Upvotes: 1