我有UITabBarController
,有4个标签。这些标签中的每一个都是单独的UIViewController
。我在这4个VC中的每一个上都有对象,这些对象在按某个对象时使用NSNotification
来执行操作。 4个VC都以相同的方式响应通知,因为它是每个页面上的类似对象。按下此对象时,它会在当前视图控制器上显示一个视图。问题是,如果我移动到其他3个选项卡中的任何一个,那么该视图也在他们的VC上。这是因为当在任何VC上按下通知时,所有4个选项卡上的响应都被响应。我需要它只响应用户当前所在的VC而不是标签栏中的任何其他VC。
有没有办法让它正常工作?也许是一个阈值,您可以在其中设置通知在被调用后执行其选择器的次数?这样我可以将它设置为1,并且在任何给定时间如果调用该通知,则只能调用一次选择器。
我正在使用的对象实现类型要求我使用NSNotificatio
n,因此无法改变我的交互方式。
编辑:
此viewDidLoad
方法位于我标签栏中4个VC的顶级VC上。它们中的所有4个都直接使用它或继承它。
- (void) viewDidLoad
{
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSelectItemFromCollectionView:) name:@"didSelectItemFromCollectionView" object:nil];
}
动作处理程序:
- (void) didSelectItemFromCollectionView:(NSNotification *)notification
{
NSDictionary *cellData = [notification object];
if (cellData)
{
NewVC *pushToVC = [self.storyboard instantiateViewControllerWithIdentifier:@"PushToVC"];
[self.navigationController pushViewController:pushToVC animated:YES];
}
}
4个VC中的每一个都是UITableViewController
,并且具有可以按下的对象的单元格。此NSNotificationCenter
操作允许操作工作。
答案 0 :(得分:4)
您必须在每个NSNotificationCenter
-addObserver:selector:name:object:
中实施-viewDidLoad
的{{1}}方法
viewController
不要在- (void)viewDidLoad
{
//...
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doSomething:)
name:@"TestNotification"
object:nil];
}
中将其移到-viewDidLoad
内,而是在-viewWillAppear
中实施removeObserver:name:object:
。
这样,只有当前 on 的-viewWillDisappear
才会响应通知。
viewController
- (void)viewWillAppear:(BOOL)animated
{
//...
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doSomething:)
name:@"TestNotification"
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
//...
[NSNotificationCenter defaultCenter] removeObserver:self
name:@"TestNotification"
object:nil];
}
修改强>
你(@Jonathan)评论道:
我非常感谢你的回答,这对我帮助很大!一世 实际上遇到了这个问题发生的另一个场景,我是 不知道如何弄清楚。现在我有一个VC呈现 另一个VC模态。每个人都有相同的观察员 NSNotification。当我进入时,一切都表现得非常好 模态提出VC,但是一旦我解雇那个VC并返回 潜在的,我有相同的问题通知 多次召唤。你对这方面的解决方案有所了解吗? 情况?
现在......关于这个......
首先......注意:
- (void)doSomething:(NSNotification *)userInfo
{
//...
//if you push a viewController then the following is all you need
[self.navigationController pushViewController:vcSomething
animated:YES];
//however.... if you're instead presenting a viewController modally then
//you should implement "-removeObserver:name:object: in this method as well
//[NSNotificationCenter defaultCenter] removeObserver:self
// name:@"TestNotification"
// object:nil];
//[self presentViewController:vcSomething
// animated:YES
// completion:nil];
//OR... in the completion parameter as:
//[self presentViewController:vcSomething
// animated:YES
// completion:^{
// [NSNotificationCenter defaultCenter] removeObserver:self
// name:@"TestNotification"
// object:nil];
// }];
}
将多次注册指定的通知(表示...相同的通知被注册N次将调用目标选择器N次)-addObserver:selector:name:object:
提示ViewController(称之为儿童)将 NOT 调用{{1}父母的
在哪里...... viewController
仍然会调用父 -viewWillDisappear:
醇>
这会在逻辑中产生不平衡,如果不处理(根据上面viewController
方法的代码示例中的注释行),则会导致 Parent 注册多次通知(因为它-viewWillAppear:
方法被调用的频率高于doSomething
)
答案 1 :(得分:0)
它应该只调用一次,以便永远不会被再次调用
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(methodName:) name:@"name" object:nil];
});