ios - TabBarController 的 NSNotification

标签 ios objective-c swift nsnotificationcenter

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

BVC
- CustomView (Notification received updates this VC) 

现在我从 BVC 中继承了 4 个不同的 Controller 。

BVC
|-- FirstVC (FVC)
|-- SecondVC (SVC)
|-- ThirdVC (TVC)

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

TabBarController
|- NVC->FVC
|- NVC->SVC
|- NVC->TVC

我的问题是,我从一个 AVPlayer 实例的 Singleton 对象发送了一个 playWillBegin 通知。从顶部事件的 VC 收到通知,但如果我不快速切换选项卡,则其他 Controller 不会收到通知。

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

我的项目都是代码,不使用 Storyboard 等。所以我的 TabBarController 是一个快速类,那里有项目,AppDelegate 中有 TabBarController 实例

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

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

init() {
    super.init() //Please refer image for error message
}

required init?(coder aDecoder: NSCoder) {

}

标签栏 Controller

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]

     } 
}

enter image description here

最佳答案

非事件选项卡未收到通知的第一个原因是不可见 Controller 已取消订阅。例如,当您从选项卡 #2 (SecondVC) 切换到选项卡 #1 (FirstVC) 时,-[viewWillDisappear:]SecondVC 调用并且它停止监听,因此 Controller 将不再接收通知。

我建议在 -[viewDidLoad:] 中开始监听并在 -[dealloc] 中停止(或在 Swift 中为 deinit):

objective-C :

- (void) viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someFunction:) name:@"notification_name" object:nil];
}

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

swift :

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(BaseController.someFunction), name:Notification.Name("foobar"), object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

第二个原因是 View 可能还没有加载,因此 [-viewDidLoad:] 没有被调用,相应的 View Controller 也没有被订阅。要解决这个问题,您可以在创建选项卡的 View Controller 时强制加载 VC 的 View ,例如:

objective-C :

FirstVC *vc1 = [FirstVC new];
[vc1 view];    // loading view, subscribing

swift :

let vc1 = FirstVC()
let _ = vc1.view

更新

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

objective-C :

- (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 :

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)
}

关于ios - TabBarController 的 NSNotification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41466056/

相关文章:

ios - UITextField 未在函数中注册任何文本长度

iOS:图像在 UIImageView 中显示不正确

iphone - 如何使用 ASIFormDataRequest 到 NSDictionary 对象的 http post 数组

ios - 如何在具有两个 Storyboard iOS Swift 的项目中初始化 View Controller

ios - 使用滑动手势更改 View Controller

ios - Twitter 消息发布问题(iOS 应用程序中的请求失败,错误为 : Error Domain=HTTP Code=410 "The operation couldn’ t be completed.

ios - 如何在 iOS 上的 Objective-C 中获取两个字符串之间的 NSString?

ios - iOS 中的图像旋转

objective-c - 我正在使用 PH 照片库来获取所有照片和视频

ios - 为什么 swift GCD 不能在 tableview cell imageView 中工作