Когда «программно» создается UINavigationController и UITabBarController, как мне обращаться к их функциям (например, viewWillAppear?) - PullRequest
5 голосов
/ 07 февраля 2010

Я создаю свои Nav и TabBar в коде при запуске через: IN: 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» не имеет элемента управления «тег». Таким образом, если я использую имя файла изображения, которое является именем категории, я могу использовать это имя файла, чтобы различать категории ... или даже имя навигационного элемента. Мне нужно знать, есть ли у ResortsListViewController способ узнать, какой щелчок элемента панели вкладок вызвал его отображение. Я думал искать «действие», которое я мог бы назначить элементу панели вкладок, но это не тот способ, которым работает tabbarcontroller.

  2. При переходе с одной вкладки на другую представление действительно изменяется, изменяется заголовок ResortsListViewController и т. Д., Но удерживаемая таблица TABLEVIEW не очищается и не отображает какие-либо новые данные. При поиске в Интернете я нашел возможное решение:

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

в основном говорят:

Для UINavigationControllers отправлять "ViewWill / ли / Появляются / Disappear" сообщения, оно должно быть получено "viewWill / Сделано / Появляются / Исчезают" из его контейнер.

Что такое контейнер для моих контроллеров UINavigation в этой ситуации? myAppDelegate определяется в файле .h как:

NSObject <UIApplicationDelegate, CLLocationManagerDelegate>

и не имеет:

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

раздел. Когда я добавляю один из них, в отладчике написано «NSObject может не отвечать на -viewWillAppear».

Есть какая-нибудь помощь?

Ответы [ 3 ]

2 голосов
/ 07 февраля 2010

1) Это довольно просто. Вам необходимо установить свойство делегат для UITabBarController. Вы должны установить это на объект контроллера, который владеет вашим 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

Дайте мне знать, если я неправильно понял вторую часть вашего вопроса.

1 голос
/ 08 февраля 2010

Хорошо, вот так: - это правильный ответ на вопрос, однако, это не оказалось таким сложным. Все, что мне нужно было сделать, это следующее:

Создайте свойство в 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 и создаю элементы в коде большую часть времени ... что я не знаю, насколько быстро это выполнить. Я склонен думать нет ... но у меня нет доказательств обратного.

0 голосов
/ 06 декабря 2011

Пожалуйста, посетите Как программно добавить UINavigationController

Пожалуйста, перейдите по ссылке выше и получите всю информацию, касающуюся UINavigationController.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...