ios - NSNotification 被 UITabBarController 多次调用

标签 ios objective-c uitabbarcontroller nsnotificationcenter

我有一个 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?

现在...关于这个...

首先...注意:

  1. 多个-addObserver:selector:name:object:将多次注册指定的通知(意味着...注册 N 次的相同通知将调用目标选择器 N 次)
  2. 父级呈现一个ViewController(称之为子级)viewController不会调用-viewWillDisappear:家长的
    哪里...
  3. 解雇 child viewController仍会调用 -viewWillAppear: parent

这会造成逻辑不平衡,如果不处理(根据上面 doSomething 方法的代码示例中的注释行),则会导致 Parent 注册通知倍数次(因为 -viewWillAppear: 方法被更频繁地调用 -viewWillDisappear: )

另请参阅:similar question

关于ios - NSNotification 被 UITabBarController 多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21029468/

相关文章:

iphone - 使用 Objective-C 上传图像

ios - 在 UIWebView 中拦截粘贴操作 (Swift)

objective-c - 如何通过Health Kit将健康记录添加到健康App

iphone - 如何最小化iPhone中点击按钮时的应用程序?

ios - UITextview底部的渐变层

ios - 通过按 UIButton 将 UILabel 的文本更改为随机数组对象

iphone - 将 NSDictionary 的 NSArray 保存到文件

ios4 - iPhone : How to switch tabs with an animation?

iphone - 以编程方式将 UINavigationBarController 作为第一个选项卡添加到现有导航 Controller 中

ios - 选项卡栏子 viewWillAppear 不会触发,添加 NavigationController 会提供两个导航栏