我有一个BaseController(BVC),我已经开始在viewWillAppear&停止在viewWillDisappear方法中听取它们。
BVC
- CustomView (Notification received updates this VC)
现在我已经从BVC继承了4个不同的控制器。
BVC
|-- FirstVC (FVC)
|-- SecondVC (SVC)
|-- ThirdVC (TVC)
现在,我有一个通过NavigationViewController(NVC)将这3个VC作为项目的TarBarController
TabBarController
|- NVC->FVC
|- NVC->SVC
|- NVC->TVC
我的问题是,我发送了一个来自Singleton对象的playWillBegin通知,这是一个AVPlayer实例。从VC收到通知,该通知在顶部处于活动状态,但如果我不快速切换选项卡,则不会在其他控制器中收到通知。
我也读过SO,其他VC没有实例化,这就是没有收到通知的原因。但我不能在VC中使用init方法,因为它要求我使用initWithaCoder
我的项目是所有代码,不使用故事板等。所以我的TabBarController是一个快速类,有项目和AppDelegate中的TabBarController实例
编辑2:澄清为什么我无法在VC的init()方法中添加任何内容 BaseViewController - 代码段
init() {
super.init() //Please refer image for error message
}
required init?(coder aDecoder: NSCoder) {
}
TabBarController
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]
}
}
答案 0 :(得分:1)
非活动标签未收到通知的第一个原因是取消订阅了不可见的控制器。当您从标签#2(SecondVC
)切换到标签#1(FirstVC
)时,会为-[viewWillDisappear:]
调用SecondVC
停止收听,因此控制器不再接收通知。
我建议开始在-[viewDidLoad:]
收听并停在-[dealloc]
(或Swift中的deinit
):
<强>的OBJ-C:强>
- (void) viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someFunction:) name:@"notification_name" object:nil];
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
<强>夫特:强>
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:强>
FirstVC *vc1 = [FirstVC new];
[vc1 view]; // loading view, subscribing
<强>夫特:强>
let vc1 = FirstVC()
let _ = vc1.view
<强>更新强>
假设您可以使用初始化程序(如下面的评论中的@danh所述),最好使用init
方法而不是viewDidLoad
进行订阅。在这种情况下,无需强制加载视图,您可以省略[vc view]
次调用:
<强>的OBJ-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;
}
<强>夫特:强>
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)
}