Подавить moreNavigationController в пользовательском UITabBarController
Я реализовал пользовательское решение UITabBar для проекта. По сути, если есть более 5 элементов, я использую scrollView, который позволит пользователю прокручивать дополнительные элементы вкладки и подавляет кнопку "больше". Подобный внешний вид можно увидеть в приложении Weather Channel.
Каждый элемент панели вкладок соответствует UINavigationController, который управляет стеком представлений для каждой вкладки. У меня возникает проблема, когда у меня более 5 элементов вкладки, начиная с вкладки 5 и далее неправильно работает стек навигации. Кажется, что moreNavigationController убивает стек навигации каждый раз, когда вы возвращаетесь на эту вкладку, и вы снова переходите на начальную страницу.
Я переопределил метод setSelectedViewController следующим образом:
- (void) setSelectedViewController:(UIViewController *)selectedViewController {
[super setSelectedViewController:selectedViewController];
if ([self.moreNavigationController.viewControllers count] > 1) {
self.moreNavigationController.viewControllers = [[NSArray alloc] initWithObjects:self.moreNavigationController.visibleViewController, nil];
}
}
Этот код удалит функциональность More на левой навигационной кнопке, но не решит проблему поддержки стека навигации. Все остальные вкладки работают нормально. Я могу просмотреть несколько представлений, и после того, как я уйду и вернусь к этой вкладке, стек сохраняется. Я понимаю, что это сложный вопрос, поэтому, пожалуйста, дайте мне знать, если есть области, где я могу внести ясность. Спасибо!
2 ответа
Вот как я это исправил:
- (void) setSelectedViewController:(UIViewController *) selectedViewController {
self.viewControllers = [NSArray arrayWithObject:selectedViewController];
[super setSelectedViewController:selectedViewController];
}
По сути, любая вкладка от 5 on заменяет свой контроллер навигации на moreNavigationController, когда вы изначально устанавливаете viewControllers на UITabBarController. Поэтому я динамически устанавливаю viewControllers так, чтобы он просто содержал вкладку, на которую я нажимаю. В этом случае никогда не будет больше 1, поэтому moreNavigationController не вступит в игру.
Когда я запускаю свой пользовательский контроллер, я просто предоставляю первую вкладку как viewControllers, чтобы приложение могло загружаться.
- (id) init {
self = [super init];
if (self) {
self.delegate = self;
[self populateTabs];
}
return self;
}
- (void) populateTabs {
NSArray *viewControllers = [self.manager createViewsForApplication];
self.viewControllers = [NSArray arrayWithObject:[viewControllers objectAtIndex:0]];
self.tabBar.hidden = YES;
MyScrollingTabBar *tabBar = [[MyScrollingTabBar alloc] initWithViews:viewControllers];
tabBar.delegate = self;
[self.view addSubview:tabBar];
}
Для ясности делегат tabBar настроен на этот класс, чтобы он мог реагировать на нажатия вкладок. Метод делегата выглядит следующим образом:
- (void) tabBar:(id) bar clickedTab:(MyScrollingTabBarItem *) tab {
if (self.selectedViewController == tab.associatedViewController) {
[(UINavigationController *) tab.associatedViewController popToRootViewControllerAnimated:YES];
} else {
self.selectedViewController = tab.associatedViewController;
}
// keep nav label consistent for tab
self.navigationController.title = tab.label.text;
}
Вы также можете переопределить переменную moreNavigationController из UITabBarController
и верните свой собственный NavigaitonContorller следующим образом:
override var moreNavigationController: UINavigationController {
return MyCustomNavController()
}
работал в моем случае, когда мне был нужен NavigaitonController, который позволял скрывать панель навигации при прокрутке.
Что касается сокрытия кнопки "Назад" в MoreNavigationController, вы можете установить leftBarButtonItem каждого NavigationItem на что угодно (даже пустой UIBarButtonItem) и обратный поток более NavigaitonController исчезнет.