我有一个 UITabBarController
,它有 4 个选项卡。这些选项卡中的每一个都是一个单独的 UIViewController。我在这 4 个 VC 上都有对象,它们使用 NSNotification 在按下某个对象时执行操作。 4 个 VC 都以相同的方式响应通知,因为每个页面上都有一个相似的对象。当按下该对象时,它会在当前 View Controller 上呈现一个 View 。问题是,如果我现在移动到其他 3 个选项卡中的任何一个,该 View 也会出现在他们的 VC 上。这是因为当在任何 VC 上按下通知时,所有 4 个选项卡都会响应通知。我需要它只响应用户当前所在的 VC,而不响应选项卡栏中的任何其他 VC。
有没有办法让它正常工作?也许是一个阈值,您可以在其中设置通知在被调用后可以执行其选择器的次数?这样我就可以将其设置为 1,并且在任何给定时间,如果调用该通知,则选择器只能被调用 1 次。
我正在使用的对象实现类型要求我使用 NSNotification,因此无法更改我的交互方式。
编辑:
此 viewDidLoad
方法位于我的选项卡栏中 4 个 VC 的顶级 VC 上。他们全部 4 个要么直接使用它,要么继承它。
- (void) viewDidLoad
{
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSelectItemFromCollectionView:) name:@"didSelectItemFromCollectionView" object:nil];
}
Action 处理程序:
- (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 操作是允许操作工作的。
最佳答案
您必须已实现 NSNotificationCenter
的-addObserver:selector:name:object:
-viewDidLoad
中的方法每个viewController
示例:
- (void)viewDidLoad
{
//...
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doSomething:)
name:@"TestNotification"
object:nil];
}
而不是将其放在 -viewDidLoad
中,将其移至-viewWillAppear
内并实现removeObserver:name:object:
在-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];
}
- (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];
// }];
}
编辑:
您(@Jonathan)评论道:
I really appreciate your answer and it has helped me out a lot! I actually ran into one more scenario where this issue occur's and I'm not sure how to figure it out. Right now I have a VC that presents another VC modally. Each one has observers for the same NSNotification. Everything performs perfectly well when I'm in the modally presented VC, but once I dismiss that VC and return to the underlying one I have the same issue where the notification is being called multiple times. Do you have an idea for a solution in this case?
现在...关于这个...
首先...注意:
- 多个
-addObserver:selector:name:object:
将多次注册指定的通知(意味着...注册 N 次的相同通知将调用目标选择器 N 次) - 从父级呈现一个ViewController(称之为子级)
viewController
将不会调用-viewWillDisappear:
家长的
哪里... - 解雇 child
viewController
仍会调用-viewWillAppear:
parent 的
这会造成逻辑不平衡,如果不处理(根据上面 doSomething
方法的代码示例中的注释行),则会导致 Parent 注册通知倍数次(因为 -viewWillAppear:
方法被更频繁地调用 -viewWillDisappear:
)
另请参阅:similar question
关于ios - NSNotification 被 UITabBarController 多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21029468/