James Raitsev
James Raitsev

Reputation: 96541

Is it possible to pass data as part of NSNotifications?

Scenario, in context of a card game:

User moves a card on the screen. As a result of a move, coordinates of the card change. If card is found to be in some specific location, we'd like to make sure Card object (Model) is updated to include those coordinates.

But View should not be talking to the Model directly .., so

Instead of updating Card directly, View is going to notify its Controller that "Card has landed". Upon receiving this notification, i'd like for a Controller to update Card's location instead of the View (Controller updates Model)

Question 1: Am i thinking about this type of scenario correctly?

Question 2: Is it possible to send data to a controller along with a notification?

Upvotes: 2

Views: 80

Answers (3)

giorashc
giorashc

Reputation: 13713

I agree that no notifications are needed. Usually for UI object coordinates I won't use a model object because the coordinates are coupled to the UI object (or else where will you draw it ?). What you do need to do is register your controller to the touch end event passing in the UI object where the touch was made and updating (in the responding controller method) the object's coordinates if they indeed within the desired location. (as done with buttons and other UI objects)

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727067

You do not need NSNotifications for your scenario: a straightforward delegate-based approach should do.

The view should define a delegate interface, and provide a non-retaining delegate property. The controller should implement the delegate interface, and set itself as view's delegate. The view would then notify its delegate without even knowing that it notifies the controller. The controller would then pass the notification along to the model.

@protocol CardDelegate
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos;
@end

@interface MyView
@property (weak, nonatomic,readwrite) id<CardDelegate> delegate;
@end

@implementation MyViewController
-(id)init { // This should be in your designated initializer
    self = [super init];
    if (self) {
        MyView *view = [[MyView alloc] init];
        view.delegate = self;
        self.view = view;
    }
    return self;
}
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos {
    // Update the model
}
@end

@implementation MyView
@synthesize delegate;
-(void) doSomething {
    // ...
    if (cardHasLanded) {
        [delegate cardHasLanded:card atPosition:pos];
    }
    // ... more code
}
@end

Upvotes: 2

DarkDust
DarkDust

Reputation: 92432

That's what the userInfo dictionary and object of NSNotification are used for. In this case, it's the object you want. For example:

// In your model header file

extern NSString * const CardMovedNotification;

// In your model implementation file

NSString * const CardMovedNotification = @"CardMoved";

...

[[NSNotificationCenter defaultCenter] postNotificationName:CardMovedNotification object:theCardThatMoved];

Your obversers then can get the card via [notification object]. If you need to pass more information, you'd create a dictionary and pass that as userInfo, via postNotificationName:object:userInfo:. The observer then can query it via [notification userInfo].

Upvotes: 2

Related Questions