Solved

Disable Tab Bar Item

Posted on 2010-09-08
19
2,330 Views
Last Modified: 2013-11-25
Is there a way to press a button and make one of the tab bar buttons disable or change the view of that tab bar item?
0
Comment
Question by:BTMExpert
  • 10
  • 9
19 Comments
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
You will have to swap it out with a new UITabBarItem.
Just create a new vUITabBarItem object and replace the object you don't want to hang around in the tabbar.
Set the new item array using the UITabBar.items property.

There is no way to disable an item. You can create another view and put that on top of the view you want disabled though. Make sure it does not propagate it's touch events to the view below it. (Not sure if it will by default anyway)
0
 

Author Comment

by:BTMExpert
Comment Utility
Thank you for the answer.  Can you show me how to do that.  I'm new to xcode.
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
Which one, the replacing of an item or the creation of a new view which will be placed on top of the item you want to disable?
0
 

Author Comment

by:BTMExpert
Comment Utility
replacing the view will be great.  So when the user clicks the tab bat item it goes to another view right?
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
This is the code to replace an item:

// create a new UITabBarItem, you decide what value you want to use for tagForNewItem
UITabBarItem *newItem = [[UITabBarItem alloc] initWithTitle:@"Title" image:someImageObject tag:tagForNewItem];
// create a mutable array with the tab bar items
NSMutableArray *barItems = [NSMutableArray arrayWithArray:self.tabBar.items];
// replace item, you must figure out the index of the object,
// typically you would use item.tag when you replace the item when it is clicked but
// otherwise you'll have to find a way to identify it's position in the array to be able to replace it.
[barItems replaceObjectAtIndex:item.tag withObject:newItem];
// set the new item list
self.tabBar.items = barItems;
// don't leak
[newItem release];

Then in -(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
you need to check the tag of the newly created item to decide what to do when the item is clicked.

Example:

-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
      switch(item.tag)
      {
            case tagForNewItem:
                  // perform your view change code here
            break;
            .......
      }
}
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
I'm thinking maybe I didn't understand your question.
Is this what you wanted?
0
 

Author Comment

by:BTMExpert
Comment Utility
i think you got it just one more thing to understand it better.  So the first part grabs the array of items in the tab bar and puts them in an array.  Then from there i replace the first item in the array, since that's the one i'm changing.  How does it know which ViewController and which nib file i want for the new tab bat item?

let me explain
i want the user to be able to click the first tab bar item, then click a button inside that view that sends them to another view that's on the tab bar.  when the user tries to click the first tab bar item again, it should change the view to a different first view.

i think you got it so i'm guessing the method that you sent me changes the view to what i want inside the case switch function
0
 

Author Comment

by:BTMExpert
Comment Utility
Is there a difference between using UITabBar vs. UITabBarController.  I'm using TabBarController since that's what comes with the template.

still a beginner. sorry.
0
 
LVL 2

Accepted Solution

by:
tisaksen earned 500 total points
Comment Utility
Yeah I think UITabBarController is made for conventient handling of UITabBar's. I have never used it so I can't say much about it.

Anyway, the key here is to use the delegate method (UITabBarDelegate)


-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
      switch(item.tag)
      {
            case 0:
                  // first item
                  // display the view you want the first time
                  YourViewController *ctrl = .........;
                  // addSubview or whatever you use to display it (might be a navigationController, I dont know)
            break;
            case 1:
                  // second item
            break;
            case 2:
                  // third item
                  // let's say this is the one which presents your view with a button,
                  // that when clicked, should replace the first item on the tabbar
                  // in the replace tabbar item code, set the tag of the new item to some far out value, like 9999 or whatever
                  // ie: UITabBarItem *newItem = [[UITabBarItem alloc] initWithTitle:@"Title" image:someImageObject tag:9999];
            break;
            case 9999:
                  // display the different view when the user clicks the first item on the tab bar
                  DifferentViewForFirstTabBarItem *differentView = .....
                  // addSubview or whatever you use to display it (might be a navigationController, I dont know)
                  // if you need to replace the first tab bar item again remember to set it's tag to 0 this time.
            break;
            
            // .........
      }
}

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:BTMExpert
Comment Utility
NSMutableArray *barItems = [NSMutableArray arrayWithArray:self.tabBar.items];
do i have to declare tabBar as something like UITabBarItem.  it keeps throwing an error
0
 

Author Comment

by:BTMExpert
Comment Utility
is that -(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
in the AppDelegate.m or on the view?
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
You have to assign a delegate for your UITabBar, typically this delegate is the view controller that created it.

UITabBar *tabBar = ....;
tabBar.delegate = self;

Make sure you implement the protocol in your .h file:

@interface ViewControllerName <UITabBarDelegate>

Then put the didSelectItem: method in the .m file
0
 

Author Comment

by:BTMExpert
Comment Utility
By doing it that way will i have to declare the UITabBar in every ViewController?
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
In every view controller you need to use it yes. But you can of course use the AppDelegate for the delegate and to store the UITabBar reference too.
0
 

Author Comment

by:BTMExpert
Comment Utility
For whatever reason i can't get it to work.  Should i send you my code so you can see or find what i'm missing?
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
Send me your project and I will have a look.
0
 

Author Comment

by:BTMExpert
Comment Utility
AppDelegate.h
#import <UIKit/UIKit.h>

@interface TabTestAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
    UIWindow *window;
    UITabBarController *tabBarController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

@end

AppDelegate.m
#import "TabTestAppDelegate.h"


@implementation TabTestAppDelegate

@synthesize window;
@synthesize tabBarController;


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
   
    // Override point for customization after application launch.

    // Add the tab bar controller's view to the window and display.
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];

    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}


- (void)applicationWillTerminate:(UIApplication *)application {
    /*
     Called when the application is about to terminate.
     See also applicationDidEnterBackground:.
     */
}


#pragma mark -
#pragma mark UITabBarControllerDelegate methods

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
}
*/

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed {
}
*/


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}


- (void)dealloc {
    [tabBarController release];
    [window release];
    [super dealloc];
}

@end

FirstViewController.h
#import <UIKit/UIKit.h>


@interface FirstViewController : UIViewController {
      UIButton *dis;
}

@property (nonatomic, retain) IBOutlet UIButton *dis;

-(IBAction) display:(id) sender;

@end

FirstViewController.m
@implementation FirstViewController
@synthesize dis;

-(IBAction) display:(id) sender{
      [[[[[self tabBarController] viewControllers] objectAtIndex:0] tabBarItem] setEnabled:false];
}

SecondViewController.h
@interface SecondViewController : UIViewController {
      UIButton *dis2;
}

@property (nonatomic, retain) IBOutlet UIButton *dis2;

-(IBAction) diss:(id) sender;

@end

SecondViewController.m
@implementation SecondViewController
@synthesize dis2;

-(IBAction) diss:(id) sender{
      [[[[[self tabBarController] viewControllers] objectAtIndex:0] tabBarItem] setEnabled:true];
}







This is the effect that i want kind of but instead of disabling the button i want it to show another view like we talked about.  FirstAViewController
0
 
LVL 2

Expert Comment

by:tisaksen
Comment Utility
I don't think you can use UITabBarController for this. Looks like it limits your options.. You need to set the delegate of the actual tabbar to be your AppDelegate object. Otherwise you wont be able to handle didSelect:item
0
 

Author Comment

by:BTMExpert
Comment Utility
AppDelegate.h
#import <UIKit/UIKit.h>

@interface DisDatTestAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
    UIWindow *window;
    UITabBarController *tabBarController;
      UITabBar *tabBar;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UITabBar *tabBar;

@end

AppDelegate.m
#import "DisDatTestAppDelegate.h"


@implementation DisDatTestAppDelegate

@synthesize window;
@synthesize tabBarController;
@synthesize tabBar;


-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
      switch(item.tag)
      {
            case 0:
                  // first item
                  // display the view you want the first time
                  //YourViewController *ctrl = .........;
                  // addSubview or whatever you use to display it (might be a navigationController, I dont know)
            break;
            case 1:
                  // second item
            break;
            case 2:
                  // third item
                  // let's say this is the one which presents your view with a button,
                  // that when clicked, should replace the first item on the tabbar
                  // in the replace tabbar item code, set the tag of the new item to some far out value, like 9999 or whatever
                  // ie: UITabBarItem *newItem = [[UITabBarItem alloc] initWithTitle:@"Title" image:someImageObject tag:9999];
            break;
            case 9999:
                  // display the different view when the user clicks the first item on the tab bar
                  //DifferentViewForFirstTabBarItem *differentView = .....
                  // addSubview or whatever you use to display it (might be a navigationController, I dont know)
                  // if you need to replace the first tab bar item again remember to set it's tag to 0 this time.
            break;
           
            // .........
      }
}
#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
   
    // Override point for customization after application launch.

    // Add the tab bar controller's view to the window and display.
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];

    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}


- (void)applicationWillTerminate:(UIApplication *)application {
    /*
     Called when the application is about to terminate.
     See also applicationDidEnterBackground:.
     */
}


#pragma mark -
#pragma mark UITabBarControllerDelegate methods

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
}
*/

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed {
}
*/


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}


- (void)dealloc {
    [tabBarController release];
    [window release];
    [super dealloc];
}

@end

FirstViewController.h
#import <UIKit/UIKit.h>


@interface FirstViewController : UIViewController {
      IBOutlet UIButton *dis;
}

@property (nonatomic, retain) UIButton *dis;

-(IBAction) disable:(id)sender;

@end

FirstViewController.m
#import "FirstViewController.h"
#import "DisDatTestAppDelegate.h"

@implementation FirstViewController

@synthesize dis;

-(IBAction) disable:(id)sender {
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Test" message:@"Test" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
      
      [alert show];
      [alert release];
      
      /*UIImage* anImage = [UIImage imageNamed:@""];
      UITabBarItem *newItem = [[UITabBarItem alloc] initWithTitle:@"Title" image:anImage tag:0];
      
      NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
      
      [newArray replaceObjectAtIndex:0 withObject:newItem];
      
      [self.tabBarController setViewControllers:newArray animated:YES];*/
      
      UIImage* anImage = [UIImage imageNamed:@""];
      UITabBarItem *newItem = [[UITabBarItem alloc] initWithTitle:@"Title" image:anImage tag:0];
      // create a mutable array with the tab bar items
      NSMutableArray *barItems = [NSMutableArray arrayWithArray:self.tabBar.items];
      // replace item, you must figure out the index of the object,
      // typically you would use item.tag when you replace the item when it is clicked but
      // otherwise you'll have to find a way to identify it's position in the array to be able to replace it.
      [barItems replaceObjectAtIndex:0 withObject:newItem];
      // set the new item list
      //[self.tabBarController setViewControllers:barItems animated:YES];
      // don't leak
      [newItem release];
      [anImage release];
      
}




/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
      // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
      
      // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
      // Release any retained subviews of the main view.
      // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

@end
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now