Alright so here is the deal. I have 5 tabs, 3 of them are just links. So when the user clicks on them, it actually brings them to a website using this:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{...}
So the tab bar item pretty much works as a button.
The links work just fine but the problem is that I don't want a view loaded on the click. So initially I added some [UIViewController alloc] for self.viewController (in the tab bar controller). Those view controllers are blank but they allow me to add the icon like so:
UIViewController *vc = [UIViewController alloc];
[vc1.tabBarItem setImage:[[UIImage imageNamed:#"tab-fb"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
vc1.title=#"Facebook";
All of this works fine, but when the user clicks on it, there is a blank black view. I understand this is normal, but how do I get rid of that? I want the user to be able to stay on the current view, but be led to the link.
I tried doing something like this:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
selectedIndex=[[tabBar items] indexOfObject:item];
if(selectedIndex == 1){
[self setSelectedIndex:0]; //RIGHT HERE
//...code to go to link...
}
}
but for some reason, the program does not respond to [self setSelectedIndex:0];
Any tips?
This does not work for me either in my tab bar.
However, this approach might work for you. In your app delegate didFinishLaunchingWithOptions:
MyTabBarController.delegate = self;
Then implement this delegate method in your app delegate:
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
In the method you can check for the VC like this:
if ([tabBarController.viewControllers indexOfObject:viewController] == indexOfTabToBlock) return false;
This effectively blocks the switch to that tab.
You would have to find some way to communicate this tap to the main view controller that you want to keep the user on so that it can process the link however you want. You could use a notification for example.
Related
Using Xcode 6 I have created an Tabbed Application using a storyboard with the supplied template.
I need a function to fire when the third tab of the UITabBarController is selected.
I can’t use the ViewDidLoad as I need it fire every time the view is accessed by clicking on the tab (not just the first time( and I can't use ViewWillAppear as I need specific behaviour when view is accessed via the tab as opposed to segued back to from subsequent (modal) view controllers.
Any advice would be appreciated. Many thanks in advance.
Implement this delegate method of UITabBarControllerDelegate on some UIViewController class
- (void)tabBarController:(UITabBarController *)theTabBarController didSelectViewController:(UIViewController *)viewController {
NSUInteger indexOfTab = [theTabBarController.viewControllers indexOfObject:viewController];
// Your code here
}
OR
You can subclass UITabBarController and override the following method.
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSUInteger indexOfTab = [[theTabBar items] indexOfObject:item];
// Your code here}
I have a tab bar navigation view and I would like to use one of the tab bar items to go to a twitter link either in the twitter app or safari. When you go back to the app, I would like it to be in the same view as before the tab bar item was touched.
I'm not sure if this is possible as I am new to iOS.
You may consider just directly opening the twitter link when the user selects the tab, but not actually changing tabs. Just override the tabBarController:shouldSelectViewController: delegate method and do something like this:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSInteger index = [tabBarController.viewControllers indexOfObject:viewController];
if(index == yourTwitterTabIndex){
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:#"whatever the Twitter app url is"]];
return NO;
}
return YES;
}
I need to intercept a UITabBar tap precisely so I can conditionally abort moving to the intended ViewController (i.e. conditionally dismiss the tap).
I create my UITabBar in the storyboard. The UITabBar is the root view of my entire app. One of the tabBar items is a profile page (so to speak). If a user does not yet have an account, I want to ignore their clicking on that specific tabBar item. The behavior I seek is that the user will not leave the present ViewController they are in to go to the Tab selected. But instead, I want them to segue to the registration page. Any ideas how I might do this interception?
UPDATE
I have managed to add the following method in my AppDelegate. The method is called, but the transition is not intercepted. How do I intercept and abort the transition?
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"Intercept tabBarController in app delegate tap gesture but then do nothing");
}
The NSLog line is printed, but transition still occurs.
Sounds like you are on the right path. But you should use
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
If you need more help, let me know.
You need to go with the UITabBar delegate of tabBar:didSelectItem:
Ex:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
// Use the item to do further
}
I have implemented a custom version of a search form that behaves a lot like a UISearchBar with a scope bar (but is actually pieced together programatically for UI reasons). The screen loads with a TextField, you tap in the TextField and the navigation bar animates up off the screen, the text field moves up and a segmented control appears for filtering results.
Anyway, that all works, but when I tap on one of the search results my code pushes a new ViewController. The problem is that new controller gets pushed without a navigation bar (because I used [[self navigationController] setNavigationBarHidden:YES animated:YES] when switching to the search state).
I can show the navigation bar as the new ViewController gets pushed, or even animate it in as the transition to the new ViewController appears - but all those solutions look clunky. I want it to work as if you were using a UISearchBar (actually more like the email app) in that the restored navigation bar appears to just slide in from the right as if it's part of the child view controller.
I'm hoping there'll be a simple fix... thanks
For anyone that comes to this, the solution is to make your controller the delegate of the UINavigationController, then show or hide the nav bar in your delegate methods.
Your controller needs to implement the protocol:
#interface MYSearchController() <UINavigationControllerDelegate>
Then in -(void)viewDidLoad assign your controller as the delegate:
[self navigationController].delegate = self;
Finally, implement a method like this:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(viewController == self)
{
if(_searchState && ![self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
}
else
{
if([self navigationController].navigationBarHidden)
{
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
}
}
I would like to know if there is a way to ensure that every time user presses on the "More" button in tabbar, he or she will be presented with list of views that are in there, not to show current view in which user is in. What I would like to get is always have the list of views on every time user press the "More" button.
This seems to work, but there may be some edge cases that I didn't consider.
In the appDelegate:
self.tabBarController.delegate = self;
...
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
[[viewController navigationController] popToRootViewControllerAnimated:NO];
}