Question

Is that possible to make a UIToolbarButton pass an object to its target by using some exoteric method (as it seems not to be possible using regular button use)?

I mean something like

UIBarButtonItem *Button = [[UIBarButtonItem alloc] initWithImage:buttonImage
  style:UIBarButtonItemStylePlain target:self action:@selector(doSomething:) **withObject:usingThis**];

I know I can trigger a method that will launch the full method with the object, but for the sake of elegance I was trying to minimize the code... I suspect it is not possible, but as you guys out there are insanely good you may come with an transcendental answer... who knows...

Was it helpful?

Solution

You would have to extend the UIBarButtonItem class.

Here is an example creating RCBarButtonItem class. I've used initWithTitle for ease, I'm sure you could change it...

The UIBarButtonItem Subclass

#import <UIKit/UIKit.h>

@interface RCBarButtonItem : UIBarButtonItem {
    id anObject;
}

@property (nonatomic, retain) id anObject;

- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action withObject:(id)obj;

@end

@implementation RCBarButtonItem

@synthesize anObject;

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

- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action withObject:(id)obj {
    if (self = [super initWithTitle:title style:style target:target action:action]) {
        self.anObject = obj;
    }
    return self;
}

@end

Then this could then be implemented like so:

#import "RootViewController.h"
#import "RCBarButtonItem.h"

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    RCBarButtonItem *button = [[RCBarButtonItem alloc] initWithTitle:@"Hello"
                                                               style:UIBarButtonItemStylePlain 
                                                              target:self
                                                              action:@selector(doSomething:)
                                                          withObject:@"Bye"];
    self.navigationItem.rightBarButtonItem = button;

}

- (void)doSomething:(id)sender {
    NSLog(@"%@", [(RCBarButtonItem *)sender anObject]);
}

OTHER TIPS

What I've done in this situation is create an NSDictionary property called, say, buttonArguments:

self. buttonArguments = [[NSDictionary alloc] initWithObjectsAndKeys: usingThis, Button, ... , nil];

Then in your doSomething: method, look up the object based on the sender parameter.

I prefer using categories:

UIBarButtonItem+BarButtonItem.h

@interface UIBarButtonItem (BarButtonItem)
@property (strong, nonatomic) NSDictionary *userInfo;
@end

UIBarButtonItem+BarButtonItem.m

static void *kUserInfo = &kUserInfo;

@implementation UIBarButtonItem (BarButtonItem)

- (NSDictionary *)userInfo {
    return objc_getAssociatedObject(self, kUserInfo);
}

- (void)setUserInfo:(NSDictionary *)userInfo {
    objc_setAssociatedObject(self, kUserInfo, userInfo, 
        OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top