我有一个 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 实例
编辑 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]
}
}
最佳答案
非事件选项卡未收到通知的第一个原因是不可见 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/