TabBarController中NavController下ViewController的初始化
Posted
技术标签:
【中文标题】TabBarController中NavController下ViewController的初始化【英文标题】:Initialization for ViewController under NavController in TabBarController 【发布时间】:2010-10-26 16:38:36 【问题描述】:我有一个相对常见的 TabBarController 设置,其选项卡包含以 TableViewControllers 作为其根的 NavigationControllers。我正在尝试对这些 TableViewController 之一的初始化执行一些逻辑,但似乎找不到调用的 init 函数。
我的目标是在 TableViewController(我有子类)中添加一个侦听器,它可以通过更新 navigationController.tabBarItem.badgeVluew 属性来响应事件。
我尝试将代码放入 initWithStyle: 和 init 中,但最终都没有被调用。我也尝试将它放在 viewDidLoad 中,但只有在控制器实际出现时才会调用它(我需要在控制器加载后/标签栏项目出现时立即发生)。
有谁知道在控制器初始化时我会将这段代码放在哪里?
此外,这一切都是通过界面构建器/NIB 设置的。我没有手动添加导航控制器或 tableviewcontroller,这就是为什么不清楚我需要覆盖哪些 init 函数。
【问题讨论】:
当您将表格视图控制器添加到 UINavigationController 堆栈时,您是如何初始化它们的?另外,您是否尝试过 viewWillLoad: ? 我没有初始化表格视图控制器。一切都连接在 IB 中,我告诉选项卡栏控制器“Tab1”将是一个 NavigationController,并将从“MyView”(一个单独的 NIB 文件)加载其视图。不幸的是,把它放在 viewWillLoad 中也不起作用(我假设它只是在 viewDidLoad 被调用之前立即调用) 【参考方案1】:如果您在 IB 中选择您的 UITabBarItems 之一,您将看到“从“YourView”加载的视图”。点击进入这个“灰色”视图。在 Inspector 窗口中,您将在 Attributes 选项卡(左侧的选项卡)中看到标题和将加载的 NIB 名称(我们称之为“YourNibName”)。
现在选择检查器的右侧选项卡(身份)并将类名(类旁边的组合)更改为您必须在 xcode 中创建的“YourViewController”类。不要使用已经选择的标准 ViewController。 InterfaceBuilder 加载您的 nib 并将其附加到您的 ViewController。
打开 YourNibName 并将 FilesOwner 的 Class(Inspector,右选项卡)也更改为“YourViewController”。
您的 TabBar 的 NIB 也包含一个 FilesOwner。为这个 FilesOwner 创建一个 ViewController 并将它的 Class 设置为这个 Controller(即 TabBarController)
在“TabBarController”中,您可以使用以下代码找出选择了哪个选项卡:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
if ([viewController.nibName isEqualToString:@"NIBName1"])
// Do something here, if you like. (i.e. Save the state in a string or int)
if ([viewController.nibName isEqualToString:@"NIBNAme2"])
// Do something here, if you like. (i.e. Save the state in a string or int)
...
在这里你可以做一些“全局”的事情或预初始化一些事情。这是您可以做的一件事。
你的观点的初始:
如果你选择一个Tab并且第一次显示视图(由YourViewController处理),“viewDidLoad”将在“YourViewController”中调用
- (void)viewDidLoad
// Here you can add views programatically
[self.view addSubview:myNavigationController.view];
[self.view bringSubviewToFront:myNavigationController.view];
// And if you like, do some INIT here
[super viewDidLoad];
我希望这就是你的问题。
现在关于徽章的事情。这是一个 hack,但对我来说效果很好。
头文件:
向你的控制器添加一个出口,它代表你的 TabBarController:
@interface yourController : UIViewController <UITabBarControllerDelegate>
UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@end
将 IB 中的此插座与您的 TabBar 连接。
实施:
在您的 TabBarControllerClass 中,您可以覆盖“initWithNibName”:
@synthesize tabBarController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
// Do some init here
// select your desired item (it will be loaded)
// then you can assign the badge
tabBarController.selectedIndex = 1;
tabBarController.selectedViewController.tabBarItem.badgeValue = @"222";
// and select the item you will start with
tabBarController.selectedIndex = 0;
// if you like you can add a notification, which you can activate from anywhere else
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(itemBadgeChanged:)
name:@"itemBadgeChangedNotification"
object:nil];
return self;
如果您不使用 nib,请改用 '- (void)loadView ... '。 您正在使用 TabBar 控制器的子类,也许您可以使用 'self.selectedIndex = 1;'而不是 'tabBarController.selectedIndex = 1;' 等等。试试这个
希望这会有所帮助!
【讨论】:
我已经通过与正确的 UITableViewController 子类连接的 view/tabbarcontroller 加载了控制器,但感谢您的解释。真正的问题是我需要在选择控制器之前运行逻辑之前(基本上只要调用它的初始化函数)。 tabBarController:didSelectViewController: 和 viewDidLoad 仅在您第一次进入该选项卡时被调用。我想将逻辑放在我的视图控制器子类中,该子类在创建时执行,甚至在它显示之前。 @Chris R. 嗨,我想我现在明白你的问题了。我在答案中添加了一些代码。也许这对你有用。以上是关于TabBarController中NavController下ViewController的初始化的主要内容,如果未能解决你的问题,请参考以下文章
替换 TabBarController 中选项卡的 ViewController
如何在 TabBarController 中重置 UIViewController
在 TabbarController 中呈现 NavigationalViewController
如何在运行时在 TabBarcontroller 中排列标签栏项目?
viewWillTransitionToSize 在 TabBarController 中调用错误的 ViewController