【问题标题】:When "programmatically" creating UINavigationController and UITabBarController, how do I address their functions (like viewWillAppear?)当“以编程方式”创建 UINavigationController 和 UITabBarController 时,我如何处理它们的功能(如 viewWillAppear?)
【发布时间】:2010-02-07 05:23:05
【问题描述】:

我在启动时通过以下代码创建我的 Nav 和 TabBar: 在:myAppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    // set up a local nav controller which we will reuse for each view controller
    UINavigationController *localNavigationController;

    // create tab bar controller and array to hold the view controllers
    tabBarController = [[UITabBarController alloc] init];
    NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:4];

    // setup the first view controller (Root view controller)
    RootViewController *myViewController;
    myViewController = [[RootViewController alloc] initWithTabBar];

    // create the nav controller and add the root view controller as its first view
    localNavigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];

    // add the new nav controller (with the root view controller inside it)
    // to the array of controllers
    [localControllersArray addObject:localNavigationController];

    // release since we are done with this for now
    [localNavigationController release];
    [myViewController release];

    // setup the first view controller just like the first 
    ResortsListViewController *resortsListViewController;
    resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
    resortsListViewController.title = @"Category1";
    resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image1.png"];
    resortsListViewController.navigationItem.title=@"Category1";
    localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
    [localControllersArray addObject:localNavigationController]; 
    [localNavigationController release];

    // setup the second view controller just like the first 
    ResortsListViewController *resortsListViewController;
    resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
    resortsListViewController.title = @"Category2";
    resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image2.png"];
    resortsListViewController.navigationItem.title=@"Category2";
    localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
    [localControllersArray addObject:localNavigationController]; 
    [localNavigationController release];

    // setup the third view controller just like the first 
    ResortsListViewController *resortsListViewController;
    resortsListViewController = [[ResortsListViewController alloc] initWithNibName:@"ResortsListView" bundle:nil];
    resortsListViewController.title = @"Category3";
    resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image3.png"];
    resortsListViewController.navigationItem.title=@"Category3";
    localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
    [localControllersArray addObject:localNavigationController]; 
    [localNavigationController release];

    [resortsListViewController release];

    // load up our tab bar controller with the view controllers
    tabBarController.viewControllers = localControllersArray;

    // release the array because the tab bar controller now has it
    [localControllersArray release];

    // add the tabBarController as a subview in the window
    [window addSubview:tabBarController.view];

    // need this last line to display the window (and tab bar controller)
    [window makeKeyAndVisible];


}

如您所见,我正在将 ResortsListViewController 重新用于不同的类别显示(带海滩的度假村、带泳池的度假村、带浓缩咖啡吧的度假村)......这是一个测试应用程序)我需要做几件事:

  1. 我需要能够知道哪个选项卡单击导致了 ResortsListViewController 的显示。我希望使用 TAG,但“initWithRootViewController”没有“tag”控件。因此,如果我使用作为类别名称的图像文件名,我可以使用该文件名来区分类别......甚至是导航项名称。我需要知道 ResortsListViewController 是否有办法知道哪个选项卡项单击导致它显示。我想寻找一个可以分配给标签栏项目的“动作”,但这不是 tabbarcontroller 的工作方式。

  2. 当从一个选项卡单击到另一个选项卡时,视图确实发生了变化,ResortsListViewController 的标题发生了变化,等等……但它所持有的 TABLEVIEW 不会清除并显示任何新数据。在网上搜索我找到了一个可能的解决方案:

http://discussions.apple.com/thread.jspa?threadID=1529769&tstart=0

基本上说:

为了 UINavigationControllers 发送 “viewWill/Did/Appear/Disappear” 消息,它需要已经收到 “viewWill/Did/Appear/Disappear”来自 它的容器。

在这种情况下,我的 UINavigationControllers 的容器是什么? myAppDelegate 在 .h 文件中定义为:

NSObject <UIApplicationDelegate, CLLocationManagerDelegate>

并且没有:

- (void)viewWillAppear:(BOOL)animated {
}

部分。当我添加一个时,它会在调试器中显示“NSObject 可能无法响应 -viewWillAppear”。

有什么帮助吗?

【问题讨论】:

    标签: objective-c iphone uinavigationcontroller uitabbarcontroller


    【解决方案1】:

    1) 这很简单。您需要为 UITabBarController 设置 delegate 属性。您可以将其设置为拥有您的 tabbarcontroller 的控制器对象(或您的应用程序委托,如果这是您的设置)。无论哪个对象被设置为委托,然后都会收到:

    - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
    

    - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
    

    管理选项卡选择。将这些方法之一放在您设置为委托的任何对象的实现中(您希望它是拥有所有控制器的对象)。

    2) 如果您有一个显示为选项卡选择的 UIViewController(例如 ResortsListViewController),那么您需要自己将 viewWillAppear 方法放入控制器实现中:

    @implementation ResortsListViewController
    
    - (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle {
    ...
    }
    
    ... etc. ....
    
    - (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [table reloadData];
    }
    
    ...
    
    @end
    

    如果我误解了你问题的第二部分,请告诉我。

    【讨论】:

    • 我会试试这个。将在上午(星期日)通知您。第二部分有点令人困惑,因为我可以添加 viewWillAppear XCode 不会自动完成它,它会警告“myAppDelegate”可能不会响应 -viewWillAppear。明白了吗?
    • 如果你的 appDelegate 是一个 NSObject(就像在任何标准的 Xcode 模板中一样),你的 appDelegate 不应该响应 viewWillAppear。您提到:ResortsListViewController *resortsListViewController。实现这一点的文件是您要放置 viewWillAppear 方法的位置。
    【解决方案2】:

    好的,这里是:这问题的正确答案,但是,它最终并没有这么难。我所要做的就是:

    在ResortViewController 中创建一个int 类型的属性,变量名为whichChoice(例如)。然后在 TabBarController 的设置中解决它:

    // setup the first view controller just like the first 
        ResortsListViewController *resortsListViewController;
        resortsListViewController = [[ResortsListViewController alloc]     initWithNibName:@"ResortsListView" bundle:nil];
        //  START HERE IS THE CHANGE
        resortsListViewController.whichChoice = 1;
        //  END HERE IS THE CHANGE
        resortsListViewController.title = @"Category1";
        resortsListViewController.tabBarItem.image = [UIImage imageNamed:@"image1.png"];
        resortsListViewController.navigationItem.title=@"Category1";
        localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
        [localControllersArray addObject:localNavigationController]; 
        [localNavigationController release];
    

    要找出当我的resortsListViewController 接管时点击了哪个选项卡,我只需查询类变量:whichChoice 即可得到答案。

    这样的事情很简单,你可以跳过它们。我认为你必须在 action 中传递变量,并指定它与 target 的位置,就像你在其他对象中所做的那样——但是当你提前设置好东西时时间你不必这样做。现在,话虽如此,动态设置“whichChoice”并不容易,无需多加考虑……但在设置时将其设置为变量 KNOWN 就可以了。

    对于答案#2,我只是在我的班级中放置了一个 IBOutlet 的变量样式,将其连接到桌子上,然后按照您的说明进行操作,因为没有 IBOutlet 中的变量并将其连接到桌子上,就会有没有参考表视图。出于某种原因,将表简单地连接到 VIEW“参考插座”并调用 [self.tableview reloadData] 并没有完成这项工作。

    但在大多数情况下,您的回答是正确的,并引导我朝着正确的方向前进。顺便说一句,如果您构建了 IB 元素,我真的很讨厌您必须在 IB 中右键单击并从此处拖动到此处。您应该能够使用它的 ObjectId(或其他东西)将它连接到代码中。这将更符合程序员。我知道 IB 是为了让 编程 设计师 来说更容易,但是 gee wilikers.. 很难把我的想法包起来!大多数时候我最终放弃了 IB 并在代码中创建元素......我不知道执行速度是否一样快。我倾向于认为不是……但没有相反的证据。

    【讨论】:

      【解决方案3】:

      请访问How to add UINavigationController Programmatically

      请访问上面的链接并获取有关 UINavigationController 的所有信息。

      【讨论】:

      • 这没用。为了创建上面的示例,我确实阅读了文档。他们没有完全解释我在问什么。
      • 我只尝试解释基础知识。请告诉我,在看什么?我必须帮助你。
      猜你喜欢
      • 2014-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2019-09-21
      • 2014-04-11
      相关资源
      最近更新 更多