场景,在纸牌游戏的背景下:
用户在屏幕上移动卡片。作为移动的结果,卡的坐标改变。如果发现卡片位于某个特定位置,我们希望确保更新卡片对象(模型)以包含这些坐标。
但是View不应该直接与模型交谈..所以
View不会直接更新卡,而是通知其控制器“卡已落地”。收到此通知后,我希望控制器更新卡的位置而不是视图(控制器更新模型)
问题1: 我正确地考虑这种情况吗?
问题2: 是否可以将数据与通知一起发送到控制器?
答案 0 :(得分:2)
这就是userInfo
词典和object
NSNotification
的用法。在这种情况下,它是您想要的object
。例如:
// In your model header file
extern NSString * const CardMovedNotification;
// In your model implementation file
NSString * const CardMovedNotification = @"CardMoved";
...
[[NSNotificationCenter defaultCenter] postNotificationName:CardMovedNotification object:theCardThatMoved];
然后您的观察者可以通过[notification object]
获取该卡。如果您需要传递更多信息,则需要创建一个字典并通过userInfo
将其传递为postNotificationName:object:userInfo:
。然后观察者可以通过[notification userInfo]
查询它。
答案 1 :(得分:2)
您的方案不需要NSNotifications
:基于代理的简单方法应该这样做。
视图应定义委托接口,并提供非保留delegate
属性。控制器应实现委托接口,并将其自身设置为视图的委托。然后,视图将通知其代理人,甚至不知道它通知控制器。然后控制器将通知传递给模型。
@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
答案 2 :(得分:0)
我同意不需要通知。通常对于UI对象坐标,我不会使用模型对象,因为坐标耦合到UI对象(或者你将在哪里绘制它?)。您需要做的是将控制器注册到传递触摸的UI对象中的触摸结束事件,并更新(在响应控制器方法中)对象的坐标(如果它们确实在所需位置内)。 (与按钮和其他UI对象一样)