views:

119

answers:

2

I have a bunch of NSDictionaries thats stored in an NSArray. The dictionaries store coordinates for buttons, their name, and their relating object to load when pressed (UIView).

When the button is pressed I can retrieve which button it is in string format, for example "settings" and I would like to then run the object -(void)settings{}.

Now I know how I would do it with if else statements but I would like to avoid them because they are messy and thought Key Value Bindings would be the way but I don't believe they exist on the iPhone.

Are they available on iPhone? Everything I read says no even in iOS4. If they are how would I implement this. If not is there a better way to do this other than if else statements? Could I store a reference to the UIView to push in the NSArray instead of a string and if so would this affect performance?

Cheers.

+1  A: 

Key Value Binding does existing in iOS, but you have to do it manually. You can create a class derived from "Button" and you can create a property of NSDictionary which you can assign and at time of assigning, you can start observing changes in dictionary instance, and in the delegate you can read value and assign to self.

Ok here is my button.h file

@interface MyCustomButton : NSButton

NSDictionary* store;

@end

-(NSDictionary*) store;
-(void) setStore: (NSDictionary*) v;

and here is my button.m file

@implementation MyCustomButton


-(void) dealloc{
   [self setStore: nil];
   [super dealloc];
}

-(void) loadValues:{
   // fill your loading values here
   // this is not correct you may need
   // to see help to get correct names of
   // function
   [self setText: [store stringForKey:@"buttonLabel"]];
}

-(void) setStore: (NSDictionary*) v{
   if(store!=nil){
      [store removeObserver: self forKeyPath:@"buttonLabel"];
      [store removeObserver: self forKeyPath:@"buttonX"];
      [store removeObserver: self forKeyPath:@"buttonY"];
      [store release];
   }
   if(v==nil)
      return;
   store = [v retain];
   [store addObserver: self forKeyPath:@"buttonLabel" options:0 context:nil];
   [store addObserver: self forKeyPath:@"buttonX" options:0 context:nil];
   [store addObserver: self forKeyPath:@"buttonY" options:0 context:nil];

   [self loadValues];
}

-(NSDictionary*) store{
   return [store autorelease];
}

-(void) observeValueForKeyPath: (NSString*) keyPath 
   ofObject:(id)object 
   change:(NSDictionary*)change 
   context:(void*)context{
   // here you can identify which keyPath 
   // changed and set values for yourself
   [self loadValues];
}
@end

and probably in the beginning of code or whereever you have instance of MyButton you need to do following...

MyButton* button = [[[MyButton alloc] init] autorelease];

// add button to view...

[button setStore: myDictionary];
// from this point onwards button will automatically
// change its properties whenever dictionary
// is modified
Akash Kava
I think you're onto something but your answer is confusing, could you clarify a bit more?
Rudiger
I have added sample code, I have not tested it yet, but you may need to tweak it to get it working.
Akash Kava
Thanks, was just after a bit more clarification but code works nicely too :)
Rudiger
+1  A: 

If you want to do runtime reference of classes and methods you need to have a look at Objective-C Runtime Reference. This will let you by using strings create classes and send messages to them.

willcodejavaforfood
Key Value Coding is used to access properties in an object, I see no way it would help me in this instance
Rudiger
Sorry I was confused by your misuse of the term Key Value Binding
willcodejavaforfood