Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

UIBarButtonItem customView action

jchoi1009jchoi1009 Posts: 18Registered Users
edited February 2011 in iOS SDK Development
Hello,

I have a UIToolbar filled with 5 UIBarButtonItems.
For the UIBarButtonItems, I am using a custom view like this:
button = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:image]];
button.action = @selector(myaction);
button.target = self;
The problem is, clicking on this button doesn't trigger myaction.
How do you use a custom view for UIBarButtonItem and make action work?

Or yet even better, is there a way to do initWithImage for UIBarButtonItem without losing original colors?
Post edited by jchoi1009 on

Replies

  • indiantroyindiantroy Posts: 27Registered Users
    edited March 2009
    I am not sure but you may want to check one thing.
    button.action = @selector(myaction:);
    Are you missing the colon at the end of myaction or it's just a typo? I think whenever you specify a function which will be called, you should have at least one argument that is sender of type id in the signature of the event handling method. Target-action pattern to be precise.

    Hope this helps..
  • jchoi1009jchoi1009 Posts: 18Registered Users
    edited March 2009
    indiantroy wrote: »
    I am not sure but you may want to check one thing.
    button.action = @selector(myaction:);
    Are you missing the colon at the end of myaction or it's just a typo? I think whenever you specify a function which will be called, you should have at least one argument that is sender of type id in the signature of the event handling method. Target-action pattern to be precise.

    Hope this helps..

    I don't have the colon but it is not necessary. Using button image or title instead of customView works fine.
  • Janek2004Janek2004 Posts: 40Registered Users
    edited January 2010
    jchoi1009 wrote: »
    I don't have the colon but it is not necessary. Using button image or title instead of customView works fine.

    Hey Anybody solve that problem?
    I am struggling with that for last 3 hours...
  • Janek2004Janek2004 Posts: 40Registered Users
    edited January 2010
    Janek2004 wrote: »
    Hey Anybody solve that problem?
    I am struggling with that for last 3 hours...
    Ok I gave up with adding the actions to the UIBarButtonItems in that way. Instead of that I am adding buttons (UIButton) than calling [buttonMenu addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];
    and finally adding it to the toolbar and everything works great.
    Except:
    I was trying to automate the process. I have four buttons that have the same size and they will have the same selector. So I have created two arrays, first storing the buttons and the second one storing the images. Than I wanted to set up all buttons inside a for loop:

    NSArray*buttonsArray=[[NSArray alloc]initWithObjects:buttonBack, buttonMenu, buttonNext, buttonHome, nil];
    NSArray*imagesArray=[[NSArray alloc]initWithObjects:back.image, menu.image, next.image, home.image, nil];

    for (int i=0;i<buttonsArray.count;i++)
    {
    [[buttonsArray objectAtIndex:i] setBounds:CGRectMake(0,0,65.0,30.0)];
    [[buttonsArray objectAtIndex:i] addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];
    [[buttonsArray objectAtIndex:i] setImage:[imagesArray objectAtIndex:i] forState:UIControlEventTouchUpInside];
    }


    //Creating custom bar buttons

    /* I tried also to pull the button from the array
    backItem = UIBarButtonItem alloc] initWithCustomView:[buttonArray objectAtIndex:0;
    */

    backItem = [[UIBarButtonItem alloc] initWithCustomView:buttonBack];
    homeItem = [[UIBarButtonItem alloc] initWithCustomView:buttonHome];
    menuItem = [[UIBarButtonItem alloc] initWithCustomView: buttonMenu];
    nextItem = [[UIBarButtonItem alloc] initWithCustomView:buttonNext];

    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    //Adding the items to the array:

    tabBarItems=[[NSArray alloc]initWithObjects:backItem, flexItem,homeItem, menuItem, flexItem, nextItem, nil];
    [self.toolBar setItems:tabBarItems animated:YES];

    and ... it doesn't work. Any ideas why?

    It works when I don't use for loop and write everything step by step like:
    UIButton * buttonNext = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonNext.bounds = CGRectMake(0, 0, 65.0, 30.0);
    [buttonNext setImage:next.image forState:UIControlStateNormal];
    [buttonNext addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];

    Regards,
    Janek
  • fiftysixtyfiftysixty Posts: 310Registered Users
    edited April 2010
    Janek2004 wrote: »
    Ok I gave up with adding the actions to the UIBarButtonItems in that way. Instead of that I am adding buttons (UIButton) than calling [buttonMenu addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];
    and finally adding it to the toolbar and everything works great.
    Except:
    I was trying to automate the process. I have four buttons that have the same size and they will have the same selector. So I have created two arrays, first storing the buttons and the second one storing the images. Than I wanted to set up all buttons inside a for loop:

    NSArray*buttonsArray=[[NSArray alloc]initWithObjects:buttonBack, buttonMenu, buttonNext, buttonHome, nil];
    NSArray*imagesArray=[[NSArray alloc]initWithObjects:back.image, menu.image, next.image, home.image, nil];

    for (int i=0;i<buttonsArray.count;i++)
    {
    [[buttonsArray objectAtIndex:i] setBounds:CGRectMake(0,0,65.0,30.0)];
    [[buttonsArray objectAtIndex:i] addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];
    [[buttonsArray objectAtIndex:i] setImage:[imagesArray objectAtIndex:i] forState:UIControlEventTouchUpInside];
    }


    //Creating custom bar buttons

    /* I tried also to pull the button from the array
    backItem = UIBarButtonItem alloc] initWithCustomView:[buttonArray objectAtIndex:0;
    */

    backItem = [[UIBarButtonItem alloc] initWithCustomView:buttonBack];
    homeItem = [[UIBarButtonItem alloc] initWithCustomView:buttonHome];
    menuItem = [[UIBarButtonItem alloc] initWithCustomView: buttonMenu];
    nextItem = [[UIBarButtonItem alloc] initWithCustomView:buttonNext];

    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    //Adding the items to the array:

    tabBarItems=[[NSArray alloc]initWithObjects:backItem, flexItem,homeItem, menuItem, flexItem, nextItem, nil];
    [self.toolBar setItems:tabBarItems animated:YES];

    and ... it doesn't work. Any ideas why?

    It works when I don't use for loop and write everything step by step like:
    UIButton * buttonNext = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonNext.bounds = CGRectMake(0, 0, 65.0, 30.0);
    [buttonNext setImage:next.image forState:UIControlStateNormal];
    [buttonNext addTarget:self action:@selector(navigateTo:) forControlEvents:UIControlEventTouchUpInside];

    Regards,
    Janek

    I struggled with this problem too once, and the solution I found was to make a UISegmentedControl with the custom image you want, and then setting the properties of the segmented control and creating a UIBarButtonItem with the segmented control as the custom view. The problem is still that it doesn't look like UIBarButtonItem with a string title, the background color is not the same, but it's better than using UIButton I think. Anyway, here is the code:
    UIImage *customIcon = [UIImage imageNamed:@"yourImagepng"];
    UISegmentedControl *customButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:customIcon, nil]];
    customButton.segmentedControlStyle = UISegmentedControlStyleBar;
    customButton.momentary = YES;
    [customButton addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventAllEvents];
    customBarButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
    

    For some reason you have to use UIControlEventAllEvents for the segmented control, using UIControlEventTouchUpInside doesn't work.
    <a href="http://www.fiftysixtysoftware.com"; target="_blank">Fifty Sixty Software</a><br />
    <a href="http://www.fiftysixtysoftware.com/blog"; target="_blank">iPhone development tips and tutorials</a><br />
    <br />
    <b>Apps in store:</b><br />
    <a href="htt
  • officevalentinofficevalentin Posts: 1New Users
    edited May 2010
    fiftysixty wrote: »
    I struggled with this problem too once, and the solution I found was to make a UISegmentedControl with the custom image you want, and then setting the properties of the segmented control and creating a UIBarButtonItem with the segmented control as the custom view. The problem is still that it doesn't look like UIBarButtonItem with a string title, the background color is not the same, but it's better than using UIButton I think. Anyway, here is the code:
    UIImage *customIcon = [UIImage imageNamed:@"yourImagepng"];
    UISegmentedControl *customButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:customIcon, nil]];
    customButton.segmentedControlStyle = UISegmentedControlStyleBar;
    customButton.momentary = YES;
    [customButton addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventAllEvents];
    customBarButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
    

    For some reason you have to use UIControlEventAllEvents for the segmented control, using UIControlEventTouchUpInside doesn't work.


    UIImage *customIcon = [UIImage imageNamed:imgName];
    UISegmentedControl *customButton = UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:customIcon, nil;
    customButton.segmentedControlStyle = UISegmentedControlStyleBar;
    customButton.momentary = YES;
    [customButton addTarget:self action:@selector(buttonHint:) forControlEvents:UIControlEventAllEvents];
    UIBarButtonItem *customBarButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
    self.navigationItem.rightBarButtonItem = customBarButton;
    //change the button frame
    customBarButton.customView.frame = CGRectMake(0,0,40,0);
    [customButton release];
    [customBarButton release];

    :)
  • sreichertsreichert Posts: 1New Users
    edited August 2010
    Guys,
    No need for work-arounds here, the answer is right in the property name, "customview".

    Just do the following:

    1. Create a UIView with the required frame parameters, i.e 40x40
    2. Create a UIImageView initialized with the desired UIImage
    3. Create a blank UIButton, but set its frame to that of the UIView. set the action and target on the button - the action should be the desired function call.
    4. Add The imageview and UIButton to the UIView
    5. Set the UIView to the customview property of the nav button, and you should be all set.
  • rismarisma Posts: 14Registered Users
    edited November 2010
    sreichert wrote: »
    Guys,
    No need for work-arounds here, the answer is right in the property name, "customview".

    Just do the following:

    1. Create a UIView with the required frame parameters, i.e 40x40
    2. Create a UIImageView initialized with the desired UIImage
    3. Create a blank UIButton, but set its frame to that of the UIView. set the action and target on the button - the action should be the desired function call.
    4. Add The imageview and UIButton to the UIView
    5. Set the UIView to the customview property of the nav button, and you should be all set.


    can you show me the code, cause i try your advice, but the nav button is not show anymore...
  • ali.m.habibali.m.habib Posts: 174Registered Users
    edited January 2011
    UIImage *customIcon = [UIImage imageNamed:imgName];
    UISegmentedControl *customButton = UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:customIcon, nil;
    customButton.segmentedControlStyle = UISegmentedControlStyleBar;
    customButton.momentary = YES;
    [customButton addTarget:self action:@selector(buttonHint:) forControlEvents:UIControlEventAllEvents];
    UIBarButtonItem *customBarButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
    self.navigationItem.rightBarButtonItem = customBarButton;
    //change the button frame
    customBarButton.customView.frame = CGRectMake(0,0,40,0);
    [customButton release];
    [customBarButton release];

    :)

    how change the image of this uibarbutton bar on click, because the evenet will be fire with UISegmentedControl
  • jazztptjazztpt Posts: 32Registered Users
    edited February 2011
    sreichert wrote: »
    Guys,
    No need for work-arounds here, the answer is right in the property name, "customview".

    Just do the following:

    1. Create a UIView with the required frame parameters, i.e 40x40
    2. Create a UIImageView initialized with the desired UIImage
    3. Create a blank UIButton, but set its frame to that of the UIView. set the action and target on the button - the action should be the desired function call.
    4. Add The imageview and UIButton to the UIView
    5. Set the UIView to the customview property of the nav button, and you should be all set.

    Even simpler: UIButton is a subclass of UIView. Create your button, add your action and target, and use that button as the custom view.

    You can also do this in Interface Builder -- drag a button onto the main object window (not a subview to any of your views), drag the Touch UpInside event to the appropriate selector in your File's Owner, and then in viewDidLoad:

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:myButton] autorelease];
  • Meredi86Meredi86 Posts: 1,108Registered Users
    edited February 2011
    slight side issue, but this is for an ipad right? im pretty sure the docs say that there is a max limit for the toolbar on both iOS devices and, i could be wrong, but i believe that 5 is to many for the iPhone, or is it just on the max?
    <ul><li><a href="http://www.cloud-books.co.uk"; target="_blank">www.cloud-books.co.uk</a> - easy online accounting (UK only) <a href="http://itunes.apple.com/gb/app/cloud-books/id465669146?ls=1&mt=8"; target="_blank">cloud-books on iTunes</a></li>
    <li
  • roocellroocell Posts: 98Registered Users
    edited February 2011
    jazztpt wrote: »
    Even simpler: UIButton is a subclass of UIView. Create your button, add your action and target, and use that button as the custom view.

    You can also do this in Interface Builder -- drag a button onto the main object window (not a subview to any of your views), drag the Touch UpInside event to the appropriate selector in your File's Owner, and then in viewDidLoad:

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:myButton] autorelease];

    Thanks so much. I've been doing this for a while now and this is the first time I've come across the method to use IB to create an object, but not put it in any views. This is *way* easier than doing things programmatically!

    I've used IB a lot, but always for things in my views. Other things like UIActivityIndicators I've created programtically, which is a PITA. This method is a snap!
Sign In or Register to comment.