首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSNotification for TabBarControllers

NSNotification for TabBarControllers
EN

Stack Overflow用户
提问于 2017-01-04 14:20:11
回答 1查看 574关注 0票数 0

我有一个BaseController (BVC),在这里我已经开始听viewWillAppear中的通知&停止在viewWillDisappear方法中听它们。

代码语言:javascript
复制
BVC
- CustomView (Notification received updates this VC) 

现在我已经从BVC中子类出了4个不同的控制器。

代码语言:javascript
复制
BVC
|-- FirstVC (FVC)
|-- SecondVC (SVC)
|-- ThirdVC (TVC)

现在,我有一个TarBarController,它通过NavigationViewController (NVC)将这3个VC作为它的项目。

代码语言:javascript
复制
TabBarController
|- NVC->FVC
|- NVC->SVC
|- NVC->TVC

我的问题是,我已经从一个作为playWillBegin实例的Singleton对象发送了一个AVPlayer通知。通知是从VC接收的,VC在上面是活动的,但是如果我不快速切换选项卡,通知就不会在其他控制器中收到。

我也是这样读到的,其他VC没有实例化,这就是没有收到通知的原因。但我不能在VC中使用init方法,因为它要求我使用initWithaCoder

我的项目都是代码,不使用故事板等等。所以我的TabBarController是一个快速类,在AppDelegate中有条目和TabBarController实例。

编辑1:相关的QA链接Link1 Link2

编辑2:澄清为什么我不能在VC BaseViewController -代码段的init()方法中添加任何内容

代码语言:javascript
复制
init() {
    super.init() //Please refer image for error message
}

required init?(coder aDecoder: NSCoder) {

}

TabBarController

代码语言:javascript
复制
class TabBarController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {

        tabBar.tintColor = UIColor.whiteColor()
        self.delegate = self

        let FNVC = UINavigationController(rootViewController: FVC())
        //Other initialization code 

        let SNVC = UINavigationController(rootViewController: SVC())
        //Other initialization code 

        let TNVC = UINavigationController(rootViewController: TVC())
        //Other initialization code 
        viewControllers = [FNVC, SNVC, TNVC]

     } 
}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-04 17:08:05

非活动选项卡未接收通知的第一个原因是不可见控制器没有订阅。例如,当您从选项卡#2 (SecondVC)切换到选项卡#1 (FirstVC)时,将为SecondVC调用-[viewWillDisappear:],并且它将停止侦听,因此控制器将不再接收通知。

我建议在-[viewDidLoad:]中开始听,在-[dealloc]中停止(或者用Swift中的deinit ):

Obj-C:

代码语言:javascript
复制
- (void) viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someFunction:) name:@"notification_name" object:nil];
}

- (void) dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Swift:

代码语言:javascript
复制
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(BaseController.someFunction), name:Notification.Name("foobar"), object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

第二个原因是视图可能尚未加载,因此没有调用[-viewDidLoad:],也没有订阅相应的视图控制器。要解决这个问题,在为选项卡创建视图控制器时,可以强制加载VC的视图,例如:

Obj-C:

代码语言:javascript
复制
FirstVC *vc1 = [FirstVC new];
[vc1 view];    // loading view, subscribing

Swift:

代码语言:javascript
复制
let vc1 = FirstVC()
let _ = vc1.view

更新

假设您可以使用初始化器(如下面的注释中的@danh所解释的),最好在init方法中订阅,而不是viewDidLoad。在这种情况下,不需要强制进行视图加载,您可以省略[vc view]调用:

Obj-C:

代码语言:javascript
复制
- (instancetype) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])){
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notified:) name:@"foobar" object:nil];
    }

    return self;
}

Swift:

代码语言:javascript
复制
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    NotificationCenter.default.addObserver(self, selector: #selector(BaseViewController.someFunc), name:Notification.Name("foobar"), object: nil)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41466056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档