7

Как обзор, у меня возникают проблемы с UINavigationController внутри UITabBarController, вызывающего viewWillAppear всякий раз, когда из стека открывается стек.Проблемы с UINavigationController внутри UITabBarController, viewWillAppear не вызван

От делегата, UITabBarController производится программно:

// Create views for Tab Bar 
    UINavigationController *view1 = [[UINavigationController alloc] initWithRootViewController:[[newsFeedNavigationController alloc] initWithStyle:UITableViewStylePlain]]; 
    resizedTabBatItem *tabBarItem1 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"newspaper.png"] tag:0]; 
    [view1 setTabBarItem:tabBarItem1]; 
    [tabBarItem1 release]; 

    UIViewController *view2 = [UIViewController new]; 
    resizedTabBatItem *tabBarItem2 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"speechbubble.png"] tag:1]; 
    [view2 setTabBarItem:tabBarItem2]; 
    [tabBarItem2 release]; 

.... 

// Create the tab bar controller 
    bookTabBarController = [BookTabBarController new]; 
    [[bookTabBarController view] setFrame:CGRectMake(0, 0, 320, 460)]; 

    // Add the views to it 
    NSArray *viewControllers = [NSArray arrayWithObjects:view1, view2, view3, view4, view5, nil]; 

    [[bookTabBarController tabBarController] setViewControllers:viewControllers]; 

Мой newsFeedNavigationController это просто подклассы UITableViewController (и подкласс не мешая viewWillAppear, так как он никогда не называли в newsFeedNavigationController). В нем элементы, которые при нажатии будут нажимать на новый UIViewController в стек.

Проблема заключается в том, что всякий раз, когда виды стекаются со стека, viewWillAppear никогда не вызывается в newsFeedNavigationController, а элементы в списке остаются выделенными. Я занимаюсь этим несколько часов в тот момент, когда мне нужна помощь, чтобы выяснить, что я делаю неправильно.

В моем newsFeedNavigationController я попытался добавить NSLog, чтобы узнать, вызвано ли это, или что-то я сделал, но он никогда не называется.

- (void)viewWillAppear:(BOOL)animated { 
    NSLog(@"is viewWillAppear called?"); 
    [super viewWillAppear:animated]; 
} 

Edit:

Хорошо, теперь вот что-то странное, я заметил:

Если я бегу:

[self presentModalViewController:(any UIview) animated:YES]; 

, а затем отпустить его, viewWillAppear начинает работать правильно когда появляются и толкают взгляды ... Так что теперь я в тупике. На самом деле это не решение, а, может быть, внутри того, что происходит.

ответ

1

Чтобы ответить на мой собственный вопрос, я выяснил, в чем проблема.

Для того, чтобы придерживаться Apple UITabBarController внутри UINavigationController, я написал свой собственный контроллер панели вкладок (bookTabBarController), который основан на стандартном контроллере View. Моя проблема заключалась в том, что класс не передавал viewDidAppear до класса, который управлял контроллерами представлений, поэтому он никогда не знал, что его показывают или нет.

+0

Я смущен. В своем сообщении вы сказали «UINavigationController внутри UITabBarController», и в ходе вашего последующего действия вы сказали «UITabBarController внутри UINavigationController» ... который? Потому что у меня одинаковая проблема с контроллером Nav в качестве вкладки в контроллере панели вкладок ... который, как я понимаю, должен поддерживаться. Но ViewDidAppear только начинает работать после того, как я представляю модальный вид из одного из представлений, перенаправленных на контроллер nav. Очень странно. – Steve

+0

См. Мой ответ для общего решения этой проблемы. – titaniumdecoy

+0

Это было то же самое, что и моя проблема. Прошу прощения за смущение. Первоначально у меня был UINavigationController с контроллером представления, а затем экран «home» содержал бы, по существу, следующий UITabBarController в стеке. Затем вы можете нажать новый вид в стек. Пример: UINavigationController с именем входа в систему с правами root, когда он был введен, uitabbar был нажат, а представления из таблицы можно было ввести в «главный» навигатор. Моя проблема заключалась в том, что viewWillAppear не передавался по стеку (он переходил из UINavigationController в UITabBarController, но не в представление панели вкладок). – Dandy

1

Другим решением является назначение делегата контроллера навигации. В делегатом, реализовать следующий метод:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 
    [viewController viewWillAppear:animated]; 
} 

Это гарантирует, что viewWillAppear будет вызван на любом контроллере представления, чье мнение о появляться в навигационном контроллере. Если вы это сделаете, viewWillAppear будет вызван независимо от того, появляется ли представление, потому что оно толкается, или оно появляется, потому что всплывает подвыбор.

+0

К сожалению, я пробовал этот метод, и он не работал. Ну, это сработало, но это не так. Проблема заключалась в том, что, хотя был вызван viewWillAppear: анимированный, он не передавался в subview, содержащемся на панели вкладок, потому что он явно не вызывался в представлении панели вкладокWillAppear. Но для других возникают проблемы, это потенциальное решение. Хотя, если viewWillAppear: анимированный не работает, это, вероятно, означает, что что-то еще не так (как в моем случае). – Dandy

1

Решение этой проблемы заключается в том, чтобы UIViewController, содержащий UINavigationController, передавал ему нужные сообщения. UINavigationController пересылает сообщения в соответствующий контроллер вида. Это кажется нелогичным, но оно работает.

@interface NavigationWrapperViewController : UIViewController { 
    // navigationController must be a subview of this view controller's view 
    UINavigationController *navigationController; 
} 
@property (nonatomic, assign) UINavigationController *navigationController; 
@end 

@implementation NavigationWrapperViewController 
@synthesize navigationController; 

-(void)viewWillAppear:(BOOL)animated { 
    [navigationController viewWillAppear:animated]; 
} 
-(void)viewDidAppear:(BOOL)animated { 
    [navigationController viewDidAppear:animated]; 
} 
-(void)viewWillDisappear:(BOOL)animated { 
    [navigationController viewWillDisappear:animated]; 
} 
-(void)viewDidDisappear:(BOOL)animated { 
    [navigationController viewDidDisappear:animated]; 
} 

@end

Вы можете найти более полное решение на Pastebin (который я не отправлял).

davidbenini.it и jaekwon для этого решения.

+0

Это решение немного неполное, а ссылка в виде пасты - немного синтаксический беспорядок, но я буду проклят, если это не решит мою проблему! Ты жжешь! –

1

Еще более простой трюк:

В вашем подклассе UITabBarController, переопределить:

-(void)loadView{ 

    [super loadView]; 

    //here goes the trick: 
    [self setSelectedIndex:1]; 
    [self setSelectedIndex:0]; 
} 
+0

Эта работа помогла мне, но я обнаружил, что установка индекса обратно в 0 немедленно не сработала. Мне пришлось ждать, пока не появится viewDidAppear. Другая страница не отображается или мерцает и работает, потому что вручную выбор другой вкладки в первую очередь означал, что проблематичное представление будет работать. Одно из предостережений заключается в том, что указатель, который вы установили, должен содержать очень простую страницу. Первоначально я попробовал просмотр с подзапросом, и подзадача исчезла, но все равно может взаимодействовать с пользователем, т. Е. Проблема переместилась на эту вкладку. – RowanPD

0

OK, это старый, очень старый, но я оказался здесь с подобной проблемой.

UITabViewController 
    UINavigationController 
     UITableViewController1 
     UITableViewController2 

Когда выскакивают из UITableViewController2, то viewWillAppear функция UITableViewController1 никогда не называли.

Проблема: Мой UITabViewController пользовательский класс был переопределяющим viewWillAppear без вызова супер реализации.

Смежные вопросы