How does one add UIButton to UIToolBar programmatically?

14,015

Solution 1

If you are actually wanting to add a UIBarButtonItem (not a UIButton) to the toolbar, you just create one or more UIBarButtonItems, put them in an NSArray (or NSMutableArray), and assign that array to the items property of the toolbar. See the UIBarButtonItem documentation for details. Using your code above, that might look something like this:

    NSMutableArray *items = [NSMutableArray array];
    for (int i = 0; i < [arrayOfModulesScreens count]; i++) {
        NSDictionary *dictRow = [arrayOfModulesScreens objectAtIndex:i];
        UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:[dictRow objectForKey:@"screen_title"]
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(buttonClick:)];
        [items addObject:button];
        [button release];
    }
    screensBar.items = items;

(you would, of course, then need to change your buttonClick: to expect a UIBarButtonItem instead of a UIButton).

If you're really wanting to put a UIButton in there, you first need to wrap the UIButton in a UIBarButtonItem, something like this:

UIBarButtonItem *item = [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];

Then add the item to the toolbar as above.


As for why your buttons aren't showing up in your posted code, the problem is that UIButton's buttonWithType: creates a button with zero width and zero height. You would need to resize the button (manually or by using sizeToFit after setting the title) to make it show. After fixing that, you would then see that the buttons are all on top of each other in the upper-left corner of the parent view; you would need to position them manually as appropriate.

Solution 2

I don't think you can change the navigationController directly in your code like that.

A safer way would be this:

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:[dictRow objectForKey:@"screen_title"]
                                                           style:UIBarButtonItemStyleBordered
                                                          target:self
                                                          action:@selector(buttonClick:)];
self.navigationItem.rightBarButtonItem = button;

Solution 3

ToolBar Approach

One problem with adding UIButton to UIToolBar is that width of the button and positioning of the buttons is difficult to control

Simpler Approach

Remove the toolbar and place a UIView with the background image which is identical to your toolbar. Now you can add the UIButton as a subview to that view. This way you have more control over the positioning and the width of the buttons. Also you can add other views as well.

Share:
14,015
iamtoc
Author by

iamtoc

Updated on July 01, 2022

Comments

  • iamtoc
    iamtoc almost 2 years

    I have added the toolbar using Interface Builder, but I need to add the buttons at runtime / conditionally. I'm not getting any errors, but my dynamic buttons are not appearing on the toolbar. I have verified that arrayOfModulesScreens is loaded with the data I need. At least that works (:)). Do I need to add the buttons into a UIView, then add that view to the toolbar? Just thinking outloud. Perhaps there is a better approach to begin with? Thanks in advance for any clues leading to the resolve.

    CustomFormController.h

    @interface CustomFormController : UIViewController { 
        UIToolbar *screensBar;  
    }
    

    CustomFormController.m

    EPData *epData = [[EPData alloc] init];
    NSArray *screens = [epData loadPlistIntoArray:@"Screens"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"process_module_id == %@", process_modulesID];
    NSArray *arrayOfModulesScreens = [screens filteredArrayUsingPredicate:predicate];
    
    for(int i=0; i < [arrayOfModulesScreens count]; i++) {
        NSDictionary *dictRow = [arrayOfModulesScreens objectAtIndex:i];
        UIButton *button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
        [button setTitle:[dictRow objectForKey:@"screen_title"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
        [screensBar addSubview:button];  
    }
    
  • iamtoc
    iamtoc over 12 years
    That makes perfect sense as to why there was no image showing. Thanks for touching on that as well as providing a better alternative.