Переключение на представление вкладок TabBar программно?

159

Допустим, у меня есть приложение UIButtonс одной вкладкой в ​​приложении для iPhone, и я хочу, чтобы оно открывало другую вкладку на панели вкладок TabBarController. Как бы я написал код для этого?

Я предполагаю, что я выгружаю существующее представление и загружаю определенное представление вкладки, но я не уверен, как написать код точно.

rottendevice
источник
У меня проблемы с методами, описанными выше, ребята, помогите в моем [вопросе] [1] [1]: stackoverflow.com/questions/19742416/…
Роман Сименок

Ответы:

399

Попробуйте этот код в Swift или Objective-C

стриж

self.tabBarController.selectedIndex = 1

Objective-C

[self.tabBarController setSelectedIndex:1];
Иордания
источник
8
Обратите внимание, что если индекс отображается на вкладку в контроллере представления Больше (если у вас более пяти вкладок), это не будет работать. В этом случае используйте -setSelectedViewController:.
Джо д'Андреа
После того, как я это сделал и он успешно меняет вкладки, я больше не могу нормально выбирать панель вкладок. ОБНОВЛЕНИЕ: это было как-то связано со мной, вызывающим popToRootViewController прямо перед тем, как я поменял вкладки программно.
Адам Джонс
Но как Self не будет работать, если я захочу переключить вкладку. скажем, я нажимаю на вкладку 3 и показываю alertView сейчас, когда пользователь нажимает ок, я хочу снова переключиться на вкладку 1. Сам не будет прав, поскольку это не текущий объект. Верный ?
Аликс
Это хорошо работает, но я также должен передавать данные при переключении вкладок. У меня есть ярлык на вкладке, где я переключаюсь на тот, который нужно обновить, как только я переключаю вкладку.! Любое простое решение этого?
Md Rais
@AdamJohns Как вам удалось решить вашу проблему. чтобы он вел себя как родной tabBar. он должен появиться в rootViewController при втором нажатии.
Waqas
20

Обратите внимание, что вкладки индексируются начиная с 0. Таким образом, работает следующий фрагмент кода

tabBarController = [[UITabBarController alloc] init];
.
.
.
tabBarController.selectedViewController = [tabBarController.viewControllers objectAtIndex:4];

идет к пятой вкладке в панели.

Джон Смит
источник
12

Мое мнение таково, что selectedIndexиспользование objectAtIndexне обязательно является лучшим способом переключения вкладки. Если вы переупорядочиваете свои вкладки, выбор жестко закодированного индекса может испортить ваше прежнее поведение приложения.

Если у вас есть ссылка на объект контроллера представления, на который вы хотите переключиться, вы можете сделать:

tabBarController.selectedViewController = myViewController

Конечно, вы должны убедиться, что myViewControllerдействительно есть в списке tabBarController.viewControllers.

ThomasT
источник
Мне нужно было выбрать moreNavController, и это единственный способ сделать это, насколько я знаю,
Ossir
9

Вы можете просто установить для selectedIndexсвойства UITabBarController соответствующий индекс, и представление будет изменено так же, как пользователь нажал кнопку вкладки.

Алекс Дим
источник
6
Единственным небольшим отличием является то, что метод делегата, который может информировать пользователя о переключении вкладок, не вызывается.
Брэд App App Guy
3
Настройка selectedIndexтакже не работает для меня с индексами> 4, но selectedViewControllerработает.
bugloaf
3

Я попробовал то, что предложил Disco S2, это было близко, но это то, что в итоге сработало для меня. Это было вызвано после выполнения действия внутри другой вкладки.

for (UINavigationController *controller in self.tabBarController.viewControllers)
{
    if ([controller isKindOfClass:[MyViewController class]])
    {
        [self.tabBarController setSelectedViewController:controller];
        break;
    }
}
Joped
источник
2

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

for ( UINavigationController *controller in self.tabBarController.viewControllers ) {
            if ( [[controller.childViewControllers objectAtIndex:0] isKindOfClass:[MyViewController class]]) {
                [self.tabBarController setSelectedViewController:controller];
                break;
            }
        }
StuStirling
источник
2

Как и решение Стюарта Кларка, но для Swift 3:

func setTab<T>(_ myClass: T.Type) {
    var i: Int = 0
    if let controllers = self.tabBarController?.viewControllers {
        for controller in controllers {
            if let nav = controller as? UINavigationController, nav.topViewController is T {
                break
            }
            i = i+1
        }
    }
    self.tabBarController?.selectedIndex = i
}

Используйте это так:

setTab(MyViewController.self)

Обратите внимание, что моя tabController ссылается на viewController за навигационными контроллерами. Без navigationControllers это выглядело бы так:

if let controller is T {
Json
источник
Без циклов нет контроллеров навигации: func selectViewController <ViewControllerModel> (type: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers? .First (где: {viewController в viewController - это ViewControllerModel})}
dev_
1

Я хотел иметь возможность указать, какая вкладка должна отображаться по классу, а не по индексу, так как я думал, что это дает надежное решение, которое в меньшей степени зависит от того, как вы подключите IB. Я не нашел ни решения Disco, ни Joped для работы, поэтому я создал этот метод:

-(void)setTab:(Class)class{
    int i = 0;
    for (UINavigationController *controller in self.tabBarContontroller.viewControllers){
        if ([controller isKindOfClass:class]){
            break;
        }
        i++;
    }
    self.tabBarContontroller.selectedIndex = i;
}

Вы называете это так:

[self setTab:[YourClass class]];

Надеюсь, это кому-нибудь пригодится

Стюарт Кларк
источник
Это сработало отлично! Я переписал его для Swift3 в другом ответе.
Json
1

Моя проблема немного отличается, мне нужно переключиться с одного childViewController в 1-й tabBar на домашний viewController 2-й tabBar. Я просто использую решение, предоставленное наверху:

tabBarController.selectedIndex = 2

Однако, когда он переключился на домашнюю страницу 2-й вкладки, контент становится невидимым. И когда я отлаживаю, viewDidAppear, viewWillAppear, viewDidLoad, ни один из них не вызывается. Я решил добавить следующий код в UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}
Jin
источник
0

Использовать в AppDelegate.mфайле:

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

     NSLog(@"Selected index: %d", tabBarController.selectedIndex);

    if (viewController == tabBarController.moreNavigationController)
    {
        tabBarController.moreNavigationController.delegate = self;
    }

    NSUInteger selectedIndex = tabBarController.selectedIndex;

    switch (selectedIndex) {

        case 0:
            NSLog(@"click me %u",self.tabBarController.selectedIndex);
            break;
        case 1:
            NSLog(@"click me again!! %u",self.tabBarController.selectedIndex);
            break;

        default:
            break;

    }

}
Ракеш Сингх
источник
0

Как и решение Стюарта Кларка, но для Swift 3 и использования идентификатора восстановления, чтобы найти правильную вкладку:

private func setTabById(id: String) {
  var i: Int = 0
  if let controllers = self.tabBarController?.viewControllers {
    for controller in controllers {
      if let nav = controller as? UINavigationController, nav.topViewController?.restorationIdentifier == id {
        break
      }
      i = i+1
    }
  }
  self.tabBarController?.selectedIndex = i
}

Используйте его следующим образом («Люди» и «Роботы» также должны быть установлены в раскадровке для определенного viewController и его идентификатора восстановления, или используйте идентификатор раскадровки и отметьте «использовать идентификатор раскадровки» в качестве идентификатора восстановления):

struct Tabs {
    static let Humans = "Humans"
    static let Robots = "Robots"
}
setTabById(id: Tabs.Robots)

Обратите внимание, что моя tabController ссылается на viewController за навигационными контроллерами. Без navigationControllers это выглядело бы так:

if controller.restorationIdentifier == id {
Json
источник
0
import UIKit

class TabbarViewController: UITabBarController,UITabBarControllerDelegate {

//MARK:- View Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

//Tabbar delegate method
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController
    yourView.popToRootViewController(animated:false)
}



}
Davender Verma
источник
1
Обычно лучше объяснить решение, чем просто разместить несколько строк анонимного кода. Вы можете прочитать Как мне написать хороший ответ , а также Объяснить полностью основанные на коде ответы
Anh Pham,