Програмне перемикання на перегляд вкладки TabBar?


159

Скажімо, UIButtonу мене в додатку iPhone перегляд однієї вкладки, і я хочу, щоб вона відкрила іншу вкладку на панелі вкладки TabBarController. Як би я написав код для цього?

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


У мене є проблеми з методами вище, хлопці допомагають в моїй [питання] [1] [1]: stackoverflow.com/questions/19742416 / ...
Роман Simenok

Відповіді:


399

Спробуйте цей код у Swift або Objective-C

Швидкий

self.tabBarController.selectedIndex = 1

Ціль-С

[self.tabBarController setSelectedIndex:1];

8
Зауважте, що якщо індекс відобразиться на вкладці в контролері More view (якщо у вас більше п'яти вкладок), це не працюватиме. У такому випадку використовуйте -setSelectedViewController:.
Джо Д'Андреа

Після того як я це зробив, і це успішно змінює вкладки, я більше не можу нормально вибирати панель вкладок. ОНОВЛЕННЯ: це якимось чином було пов’язано зі тим, що я викликав popToRootViewController прямо перед тим, як я поміняв вкладки програмно.
Адам Джонс

Але як самостійно працювати, якщо я хочу переключити вкладку. скажемо, я натискаю вкладку 3 і показую alertView зараз, коли користувач натискає кнопку "OK", я хочу перейти на вкладку 1 ще раз. Я не маю рацію, оскільки це не поточний об'єкт. Правильно?
Алікс

Це добре працює, але я також повинен передавати дані під час переключення вкладок. У мене є ярлик у вкладці, де я переключаюсь на цю, яку потрібно оновити, як тільки я переключуся на вкладку! Будь-яке просте рішення для цього?
Md Rais

@AdamJohns Як вам вдалося вирішити свою проблему. щоб змусити себе поводитись як рідний tabBar. він повинен спливати до rootViewController під час другого клацання.
Вакас

20

Зауважте, що вкладки індексуються починаючи з 0. Отже, наступний фрагмент коду працює

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

переходить до п’ятої вкладки в барі.


12

Моя думка, що selectedIndexвикористання або objectAtIndexне завжди є найкращим способом переключення вкладки. Якщо ви впорядкуєте вкладки, вибір жорсткого коду може бути зіпсований з поведінкою вашої колишньої програми.

Якщо у вас є посилання на об'єкт контролера перегляду, на який ви хочете перейти, ви можете:

tabBarController.selectedViewController = myViewController

Звичайно, ви повинні переконатися, що це myViewControllerдійсно в списку tabBarController.viewControllers.


Мені потрібно було вибрати більшеNavController, і це єдиний спосіб зробити це, наскільки я знаю
Ossir

9

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


6
З однією невеликою різницею є те, що метод делегата, який може інформувати про вкладки комутації користувача, не викликається.
Brad The 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;
    }
}

2

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

for ( UINavigationController *controller in self.tabBarController.viewControllers ) {
            if ( [[controller.childViewControllers objectAtIndex:0] isKindOfClass:[MyViewController class]]) {
                [self.tabBarController setSelectedViewController:controller];
                break;
            }
        }

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)

Зауважте, що моя вкладка Контролер посилається на перегляд контролерів за навігаційними контролерами. Без навігаційних контролерів це виглядатиме так:

if let controller is T {

Без НЕ зациклення, немає навігаційних контролерів: FUNC selectViewController <ViewControllerModel> (тип: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers .first (де: {ViewController в ViewController є ViewControllerModel})?}
dev_exo

1

Я хотів би мати можливість вказати, яка вкладка показана класом, а не індексом, оскільки я вважав, що це зроблено для надійного рішення, яке менш залежить від того, як ви підключите ІБ. Я не знайшов ні 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-й таб-барі на домашній виглядКонтролер 2-го вкладка. Я просто використовую рішення, надане вгорі:

tabBarController.selectedIndex = 2

Однак коли він перейшов на головну сторінку 2-го вкладка, вміст невидимий. І коли я налагоджую, viewDidAppear, viewWillAppear, viewDidLoad, ніхто з них не викликається. Мої рішення - додати наступний код у UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

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 та його ідентифікатор відновлення, або використовувати ідентифікатор Storyboard та встановити прапорець "використовувати ідентифікатор розкадрування" як ідентифікатор відновлення):

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

Зауважте, що моя вкладка Контролер посилається на перегляд контролерів за навігаційними контролерами. Без навігаційних контролерів це виглядатиме так:

if controller.restorationIdentifier == id {

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)
}



}

1
Зазвичай краще пояснити рішення, а не просто розміщувати кілька рядків анонімного коду. Ви можете прочитати Як мені написати хорошу відповідь , а також пояснити цілком кодовані відповіді
Anh Pham
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.