3
votes

I am new to iPhone. I am trying to implement KVO mechanism.

What I have?

two TabController with two UIViewController, FirstViewController has a button, SecondViewController has a UITextView

What I Want?

When button is pressed in the firstViewController, it updates member variable, which should be observed by secondViewController, and it should append to the UITextView.

What I did?

FirstViewController.h

@interface FirstViewController : UIViewController
{
    IBOutlet UIButton *submitButton;

}

-(IBAction)submitButtonPressed;

@property (retain) NSString* logString;
@end

FirstViewController.m

-(IBAction)submitButtonPressed
{
    NSLog (@" Submit Button PRessed ");
    self.logString = @"... BUtton PRessed and passing this information ";
}

SecondViewController.h

@interface SecondViewController : UIViewController
{
    IBOutlet UITextView *logView;
}

@property (nonatomic, strong) UITextView *logView;
@end

SecondViewController.m

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
  ......

  NSArray *vControllers =     [self.tabBarController  viewControllers];
    FirstViewController *fvc = [vControllers objectAtIndex:0];
    [fvc addObserver:self  forKeyPath:@"logString" options:NSKeyValueObservingOptionNew context:NULL];

  return self;
}


-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog (@".... OBSERVE VALUE FOR KEY PATH...");    
}

What output I Expect?

The String ".... OBSERVE VALUE FOR KEY PATH..." should be printed each time i press the button in the FirstViewController.

What I get?

No OUtput.

What i am doing wrong?. Kindly help me

1

1 Answers

3
votes

put your "member variable" into a separate class file ... i.e. MODEL / view / controller. Make a singleton model object holding your data, then you can KVO that model object from any view controller.

This is roughed out pseudo-code:

    @interface MyDataModel: NSObject
    {
     NSString *logString;
    }
    @property (nonatomic,retain) NSString *logString;
    @end

    @implementation MyDataModel

    @synthesize logString;

    + (MyDataModel *) modelObject
    {
     static MyDataModel *instance = nil;
     static dispatch_once_t once;
     dispatch_once(&once, ^{
       if (instance == nil)
       {
        instance = [[self alloc] init];
       }
     });

     return (instance);
    }

    @end

in your VC1

MyDataModel *model = [MyDataModel modelObject];
[model setLogString:@"test"];

in your VC2

[model addObserver:self forKeyPath:@"logString" options:0 context:NULL]; 

a more sophisticated approach would use Core Data as a persistent store and to act as your data model.