UITabBarController - don't show the view - iphone

I'm creating an iPhone app with UITabBarController.
What I want to achieve is that when I tap some items on tabbar I don't want them to activate new view, instead of it I want them to run some functionality in the current view.
For example I have a view with map active and when I click some item on tabbar I want it to locate the current position on the map.
I don't know if using UITabBarController is the best solution for this. I'll also want 1 item to swap between 2 views (map / list).
Would it be better to use some kind of ToolBar on bottom or anything completely different?
I don't think there is any code needed, but I've got a UITabBarViewController app created and I created a UITabBarControllerDelegate like this:
#interface MainTabBarControllerDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
and
#implementation MainTabBarControllerDelegate
#synthesize tabBarController, window;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
tabBarController.delegate = self;
[window addSubview:tabBarController.view];
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
}
#end
But I don't know how to achieve the functionality.
Thanks.

You're right, you don't need a UITabBarController for this. A UIToolbar or your own custom UIView would be enough. But if you want to use UITabBarController, you'll have to override its usual functioning:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
return NO; //do not select any view controller here
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
// find which tab was tapped here and handle the map's current position
// location operation accordingly
}
You can also refer to this link for more tips...

Related

CustomTabBarController not responding to delegate callbacks

I have created a custom UITabBarController by using Martin's tutorial.
My subclass FSTabBarController switches between view controllers, and acts normal as far as I can see.
The issue is, when I change my tabBarContoller to my subclass, It won't respond to my delegate;
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
If I change it back to UITabBarController -when I use the default UITabBarController- the delegates works as it should.
The custom subclass uses the below function to represent tab selection:
- (void)_buttonClicked:(id)sender
{
self.selectedIndex = [sender tag];
[self _updateTabImage];
}
Edit:
AppDelegate.h
...
#interface AppDelegate : UIResponder <UIApplicationDelegate,UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) FSTabBarController *tabBarController;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
self.tabBarController = [[FSTabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:peopleViewController,viewController,profileViewController, nil];
self.tabBarController.delegate = self;
...
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
// not called when FSTabBarController, called when UITabBarController !!
}
OK, downloaded the sample from his site and tested.
Yes you need to manually call the deleage from the subclass:
this is how you should change the buttonClicked function:
- (void)_buttonClicked:(id)sender
{
self.selectedIndex = [sender tag];
if (self.delegate) {
[self.delegate tabBarController:self didSelectViewController:self.selectedViewController];
}
[self _updateTabImage];
}

Custom Delegate, dismiss popover from another view

I could use some help with custom delegates. I'm trying to make a protocol that sends a message to its delegate to dismiss the popover view. Here is what I'm trying.
In the popoverViewController.h
#import <UIKit/UIKit.h>
#protocol MyPopoverDelegate <NSObject>
-(void) didSelectLanguage;
#end
#interface Popover : UITableViewController{
id <MyPopoverDelegate> delegate;
NSMutableArray *languageData;
}
#property (nonatomic, assign) id <MyPopoverDelegate> delegate;
#end
.m
#synthesize delegate;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"You selected %#", [languageData objectAtIndex:[indexPath row]]);
[self.delegate didSelectLanguage];
}
...
And in the ViewController that presents the popover
#import <UIKit/UIKit.h>
#import "popoverViewController.h"
#interface ChoicesChoices : UIViewController <UIPopoverControllerDelegate, MyPopoverDelegate>{
UIPopoverController *popover;
}
- (IBAction)facebook:(id)sender;
- (IBAction)twitter:(id)sender;
- (IBAction)sms:(id)sender;
- (IBAction)copy:(id)sender;
- (IBAction)email:(id)sender;
- (IBAction)home:(id)sender;
- (IBAction)mute:(id)sender;
- (IBAction)note:(id)sender;
#property (nonatomic, retain) UIPopoverController* popover;
#end
and .m
#synthesize popover;
...
- (void)didSelectLanguage{
[popover dismissPopoverAnimated:YES];
NSLog(#"didSelectLanguage fired");
}
When I select a row in the table of the popover, didSelectLanguage does not get called. Any ideas on what I might be doing wrong? Thanks for your help.
Make sure you are setting your delegate to the be the view controller that is presenting your popover. Something like this in ChoicesChoices.m:
- (void)presentPopover
{
// assuming ARC for all allocations
Popover *myController = [Popover new];
myController.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:myController];
[self.popover presentPopover...]; // two flavors here, FromRect: and FromBarButtonItem:, that's left up to you to choose which one is correct.
}
Make sure you set the delegate in the presenting view controller when you create the instance of your custom class.
popover.delegate = self
Also, it looks like your property is a standard popover controller instead of an instance of your custom view controller.

tabBar didSelectItem seems not to be working

In my header file I have this:
#interface TabBarController : UIViewController <UIApplicationDelegate, UITabBarDelegate, UITabBarControllerDelegate>{
IBOutlet UITabBarController *tabBarController;
}
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
In my main file I have this:
#synthesize tabBarController;
-(void)viewDidLoad{
[super viewDidLoad];
self.tabBarController.delegate = self;
self.view = tabBarController.view;
}
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
NSLog(#"rawr");
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[tabBarController release];
[super dealloc];
}
#end
I have already connected my tabbarcontroller as a delegate to my file's owner in interface builder, but it still never calls the didSelectItem method.
Is there anything that I'm missing here?
I have already added tabBarController.delegate = self; and it still does not work.
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
This method is a delegate method for UITabBar, not UITabBarController, so
self.tabBarController.delegate = self;
will not work.
Tab bar controller has its own UITabBar, but changing the delegate of a tab bar managed by a tab bar controller is not allowed, so just try UITabBarControllerDelegate method like this:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
You need to add this:
tabbarcontroller.delegate = self;
Use UITabBarControllerDelegate instead of UITabBarDelegate and -tabBarController:didSelectViewController{} instead of tabBar:didSelectItem{}
Interface
#interface TabBarController : UIViewController <UIApplicationDelegate, UITabBarControllerDelegate, UITabBarControllerDelegate>{
IBOutlet UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
main file
#implementation TabBarController
#synthesize tabBarController;
/*other stuff*/
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
NSLog(#"rawr");
}
/*other stuff*/
#end
Just set the delegate for the tab bar. You can do it by setting self.tabBarController.delegate = self; or using Interface builder do to the tabbarcontroller object (not bar) see the connection inspector and drag the connection on the file's owner.
You have synthesized the tab bar, so you now need to write: self.tabBarController.delegate = self;
There are many reasons, as indicated above, why it might not be working. Here is a more subtle reason. If you are creating your UI programatically (no storyboard or Xib) you need to set the screen of your UIWindow.
self.window = [[UIWindow alloc] init];
self.window.screen = [UIScreen mainScreen]; // <- The UITabViewController will not
// accept taps without this.
If you are using a Xib, I believe this is equivalent to having "Full Screen at Launch" selected. That has to be checked or I have noticed my Tabs don't work.
I had a non-working tab controller and this is what I had to do to get it working. None of the other answers on this page helped me. I suppose using a xib/storyboard is pretty rare these days (I think this was from iOS 5 days) but leaving here for the person that does and stumbles into this situation.

Subclassed? UITabBarController wont autorotate

Noobie so bear with me.
I've have been following the O'Rielyy Learning iPhone Programming and various threads on here to build my first iPhone App. So far so good, but the final stumbling block at the projects end is getting the App to autorotate (the beta using only uiwebviews was rejected for not auto-rotating)
I have the mail App delegate, which adds a UITabBarController
// myNewsUKDelegate.h
#interface myNewsUKDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
// myNewsUKDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
There is are .h and .m files for tabBarController - I added all the UINavigationControllers in IB, which in turn add a UITableView
See image at http://flatearth.co.uk/nib.png (too noob to post images in questions!)
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
The next view down/in/subclassed (whatever the correct terminology is), which has .h and .m files is the FirstViewController which adds the table view, this has shouldAutorotateToInterfaceOrientation already set.
#interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSArray *userList;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSArray *userList;
#end
#implementation FirstViewController
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
// I tried adding
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// lots of other code ; )
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
So the problem appears to be that when [self.window addSubview:tabBarController.view]; adds the tab bar it doesn't add the shouldAutorotateToInterfaceOrientation returning YES bit.
It appears that I need to add a tabBarController subclass, with the shouldAutorotateToInterfaceOrientation in it. So I read up and tried this, as suggested on the interwebs...
// tabBarController.h
#import <UIKit/UIKit.h>
#interface tabBarController : UITabBarController {
}
#end
// tabBarController.m
#import "tabBarController.h"
#implementation tabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
and adding
#import "tabBarController.h"
to myNewsUKDelegate.m
But that fails with "error: accessing unknown 'view' class method" at the
[self.window addSubview:tabBarController.view];
line in myNewsUKDelegate.m
Further searching hasn't produced anything helpful and my recent Xcode knowledge has now ran dry : ( Any help appreciated.
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
No, you don't need to do that. The tab bar controller determines if it supports a specific interface orientation or not by asking all its child controllers if they support this orientation. In your case, these seem to be navigation controllers, which in turn ask their current child controller if it supports the orientation.
In other words, you have to make sure that all your custom view controllers return YES for the desired interface orientation.
You don't need a subclass, you need a Category on UITabBarController. Basically you create a file called UITabBarController + Autoresize.h (and .m)
In the .h:
#import <UIKit/UIKit.h>
#interface UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
#end
in the .m:
#import "UITabBarController + Autoresize.h"
#implementation UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//do custom checks here if you only want to autorotate it in certain views or whatever
}
#end
but as the other poster pointed out, ALL the parent views of the view you wish to rotate must support rotation.

My UITabBarController's didSelectViewController method is not getting called?

Here is my code stub for my app-delegate.m -- it never gets called.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"%s", __FUNCTION__);
}
It is defined in this app-delegate.h
#interface OrioleAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Did you make a connection between your UITabBarController and your application delegate?
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
...
tabBarController.delegate = self;
...
}
If your ViewController is a UITabBarController, you need to set self as it's delegate because you can't change the delegate of the UITabBar directly.
For example, in the ViewDidLoad of your UITabBarController :
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
I added the following tabBarController.delegate = self; and all is well. I hope this is helpful to others.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
tabBarController.delegate = self;
[window addSubview:tabBarController.view];
}