Przełączasz się do widoku karty TabBar w sposób programowy?


159

Załóżmy, że mam UIButtonwidok jednej karty w mojej aplikacji na iPhone'a i chcę, aby otwierał inną kartę na pasku kart w TabBarController. Jak napisałem kod, aby to zrobić?

Zakładam, że wyładowuję istniejący widok i ładuję określony widok karty, ale nie jestem pewien, jak dokładnie napisać kod.


Mam problemy z powyższymi metodami, chłopaki pomagają w moim [pytaniu] [1] [1]: stackoverflow.com/questions/19742416/…
Roman Simenok

Odpowiedzi:


399

Wypróbuj ten kod w języku Swift lub Objective-C

Szybki

self.tabBarController.selectedIndex = 1

Cel C

[self.tabBarController setSelectedIndex:1];

8
Zwróć uwagę, że jeśli indeks jest mapowany na kartę w kontrolerze widoku Więcej (jeśli masz więcej niż pięć kart), to nie zadziała. W takim przypadku użyj -setSelectedViewController:.
Joe D'Andrea

Po wykonaniu tej czynności i pomyślnej zmianie kart nie mogę już normalnie wybierać paska kart. AKTUALIZACJA: było to w jakiś sposób związane z wywołaniem popToRootViewController tuż przed programową zamianą kart.
Adam Johns

Ale jak nie zadziała Self, jeśli chcę zmienić kartę. powiedzmy, że kliknę kartę 3 i pokaż alert Wyświetl teraz, gdy użytkownik naciska ok, chcę ponownie przełączyć się na kartę 1. Self nie będzie miał racji, ponieważ nie jest to obecny obiekt. Dobrze?
Alix

Działa to dobrze, ale muszę też przekazywać dane podczas przełączania zakładek. Na karcie mam etykietę, na której się przełączam, musi zostać zaktualizowana, gdy tylko zmienię kartę.! Jakieś łatwe rozwiązanie tego problemu?
Md Rais,

@AdamJohns Jak udało Ci się rozwiązać problem. aby zachowywał się jak natywny tabBar. powinien wyskoczyć do rootViewController przy drugim kliknięciu.
Waqas

20

Zwróć uwagę, że zakładki są indeksowane począwszy od 0. Tak więc działa następujący fragment kodu

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

przechodzi do piątej zakładki w pasku.


12

Moim zdaniem selectedIndexlub używanie objectAtIndexniekoniecznie jest najlepszym sposobem na zmianę karty. Jeśli zmienisz kolejność kart, wybór indeksu zakodowanego na stałe może zepsuć poprzednie zachowanie aplikacji.

Jeśli masz odniesienie do obiektu kontrolera widoku, do którego chcesz się przełączyć, możesz wykonać:

tabBarController.selectedViewController = myViewController

Oczywiście musisz się upewnić, że myViewControllernaprawdę znajduje się na liście tabBarController.viewControllers.


Musiałem wybrać moreNavController i to jedyny sposób, aby to zrobić, o ile wiem
Ossir

9

Możesz po prostu ustawić selectedIndexwłaściwość w UITabBarController na odpowiedni indeks, a widok zostanie zmieniony tak, jak użytkownik dotknął przycisku karty.


6
Z jedną małą różnicą jest to, że metoda delegata, która może informować o przełączaniu kart użytkownika, nie jest wywoływana.
Brad The App Guy

3
Ustawienie selectedIndexrównież nie działa dla mnie z indeksami> 4, ale selectedViewControllerdziała.
bugloaf

3

Wypróbowałem to, co zasugerowało Disco S2, było blisko, ale tak się skończyło. Zostało to wywołane po wykonaniu czynności w innej karcie.

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

2

W przypadkach, w których możesz przenosić karty, oto kod.

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

2

Podobnie jak rozwiązanie Stuarta Clarka, ale dla 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
}

Użyj tego w ten sposób:

setTab(MyViewController.self)

Zwróć uwagę, że mój tabController łączy do viewControllers za navigationControllers. Bez navigationControllers wyglądałoby to tak:

if let controller is T {

Bez pętli, bez kontrolerów nawigacji: func selectViewController <ViewControllerModel> (typ: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers? .First (gdzie: {viewController in viewController to ViewControllerModel})}
dev_exo,

1

Chciałem móc określić, która karta jest wyświetlana według klasy, a nie indeksu, ponieważ uważałem, że jest to solidne rozwiązanie, które jest mniej zależne od sposobu okablowania IB. Nie znalazłem rozwiązania Disco ani Jopeda do działania, więc stworzyłem tę metodę:

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

nazywasz to tak:

[self setTab:[YourClass class]];

Mam nadzieję, że to komuś pomoże


To działało świetnie! Przepisałem go dla Swift3 w innej odpowiedzi.
Json

1

Mój problem jest trochę inny, muszę przełączyć się z jednego childViewController w 1. tabBar na home viewController 2. tabBar. Po prostu korzystam z rozwiązania znajdującego się na piętrze:

tabBarController.selectedIndex = 2

Jednak po przełączeniu na stronę główną drugiego tabBar zawartość jest niewidoczna. A kiedy debuguję, viewDidAppear, viewWillAppear, viewDidLoad, żaden z nich nie jest wywoływany. Moje rozwiązanie polega na dodaniu następującego kodu w UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

0

Użyj w AppDelegate.mpliku:

(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

Podobnie jak rozwiązanie Stuarta Clarka, ale dla Swift 3 i używając identyfikatora przywracania, aby znaleźć właściwą kartę:

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
}

Użyj go w ten sposób („Ludzie” i „Roboty” muszą być również ustawione w scenorysie dla określonego kontrolera widoku i jego identyfikatora przywrócenia lub użyj identyfikatora scenorysu i zaznacz „użyj identyfikatora scenorysu” jako identyfikatora przywrócenia):

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

Zwróć uwagę, że mój tabController łączy do viewControllers za navigationControllers. Bez navigationControllers wyglądałoby to tak:

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
Zwykle lepiej jest wyjaśnić rozwiązanie, zamiast publikować kilka wierszy anonimowego kodu. Możesz przeczytać Jak napisać dobrą odpowiedź , a także wyjaśnić odpowiedzi w całości oparte na kodzie
Anh Pham
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.