Programmgesteuert zu einer TabBar-Registerkartenansicht wechseln?

159

Angenommen, ich habe eine UIButtonAnsicht in einer Registerkarte in meiner iPhone-App und möchte, dass eine andere Registerkarte in der Registerkartenleiste von geöffnet wird TabBarController. Wie würde ich den Code dazu schreiben?

Ich gehe davon aus, dass ich die vorhandene Ansicht entlade und eine bestimmte Registerkartenansicht lade, bin mir aber nicht sicher, wie ich den Code genau schreiben soll.

rottendevice
quelle
Ich habe Probleme mit den oben genannten Methoden, Jungs helfen in meiner [Frage] [1] [1]: stackoverflow.com/questions/19742416/…
Roman Simenok

Antworten:

399

Versuchen Sie diesen Code in Swift oder Objective-C

Schnell

self.tabBarController.selectedIndex = 1

Ziel c

[self.tabBarController setSelectedIndex:1];
Jordanien
quelle
8
Beachten Sie, dass dies nicht funktioniert, wenn der Index einer Registerkarte im Controller "Mehr Ansicht" zugeordnet ist (falls Sie mehr als fünf Registerkarten haben). In diesem Fall verwenden -setSelectedViewController:.
Joe D'Andrea
Nachdem ich dies getan habe und die Registerkarten erfolgreich geändert wurden, kann ich die Registerkartenleiste nicht mehr normal auswählen. UPDATE: Das hatte irgendwie damit zu tun, dass ich popToRootViewController aufgerufen habe, bevor ich die Registerkarten programmgesteuert ausgetauscht habe.
Adam Johns
Aber wie Selbst nicht funktioniert, wenn ich die Registerkarte wechseln möchte. Angenommen, ich klicke auf Tab. 3 und zeige alertView jetzt an, wenn der Benutzer OK drückt. Ich möchte wieder zu Tab 1 wechseln. Selbst wird nicht richtig sein, da es nicht das aktuelle Objekt ist. Richtig ?
Alix
Dies funktioniert gut, aber ich muss auch die Daten übergeben, während ich die Registerkarten wechsle. Ich habe eine Beschriftung in der Registerkarte, zu der ich wechsle, die aktualisiert werden muss, sobald ich die Registerkarte wechsle.! Irgendeine einfache Lösung dafür?
Md Rais
@AdamJohns Wie haben Sie es geschafft, Ihr Problem zu lösen? damit es sich wie eine native tabBar verhält. Beim zweiten Klick sollte es in rootViewController angezeigt werden.
Waqas
20

Beachten Sie, dass die Registerkarten ab 0 indiziert sind. Das folgende Codefragment funktioniert also

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

geht zur fünften Registerkarte in der Leiste.

John Smith
quelle
12

Meiner Meinung nach ist selectedIndexoder objectAtIndexist nicht unbedingt der beste Weg, um die Registerkarte zu wechseln. Wenn Sie Ihre Registerkarten neu anordnen, kann eine fest codierte Indexauswahl Ihr früheres App-Verhalten beeinträchtigen.

Wenn Sie die Objektreferenz des Ansichtscontrollers haben, zu dem Sie wechseln möchten, haben Sie folgende Möglichkeiten:

tabBarController.selectedViewController = myViewController

Natürlich müssen Sie sicherstellen, dass das myViewControllerwirklich in der Liste von steht tabBarController.viewControllers.

ThomasT
quelle
Ich musste moreNavController auswählen und es ist der einzige Weg, dies zu tun, soweit ich weiß
Ossir
9

Sie können die selectedIndexEigenschaft auf dem UITabBarController einfach auf den entsprechenden Index setzen, und die Ansicht wird geändert, sobald der Benutzer auf die Registerkarte tippt.

Alex Deem
quelle
6
Der einzige kleine Unterschied besteht darin, dass die Delegatenmethode, die über die Benutzerwechselregisterkarten informieren kann, nicht aufgerufen wird.
Brad The App Guy
3
Die Einstellung selectedIndexfunktioniert bei Indizes> 4 auch nicht, funktioniert aber selectedViewController.
Bugloaf
3

Ich habe versucht, was Disco S2 vorschlug, es war knapp, aber das hat letztendlich für mich funktioniert. Dies wurde aufgerufen, nachdem eine Aktion auf einer anderen Registerkarte ausgeführt wurde.

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

In Fällen, in denen Sie möglicherweise die Registerkarten verschieben, finden Sie hier einen Code.

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

Wie Stuart Clarks Lösung, aber für 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
}

Verwenden Sie es so:

setTab(MyViewController.self)

Bitte beachten Sie, dass mein tabController hinter viewControllers auf viewController verweist. Ohne Navigationscontroller würde es so aussehen:

if let controller is T {
Json
quelle
Ohne Looping, keine Navigation - Controller: func selectViewController <ViewControllerModel> (Typ: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers .First (wobei: {Viewcontroller in Viewcontroller ist ViewControllerModel})?}
dev_exo
1

Ich wollte in der Lage sein anzugeben, welche Registerkarte von der Klasse und nicht vom Index angezeigt wird, da ich dachte, dass dies eine robuste Lösung darstellt, die weniger davon abhängt, wie Sie IB verkabeln. Ich habe weder Disco noch Joped gefunden, um zu funktionieren, also habe ich diese Methode erstellt:

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

Sie nennen es so:

[self setTab:[YourClass class]];

Hoffe das ist hilfreich für jemanden

Stuart Clark
quelle
Das hat super geklappt! Ich habe es für Swift3 in einer anderen Antwort umgeschrieben.
Json
1

Mein Problem ist etwas anders. Ich muss von einem childViewController in der 1. TabBar zu einem Home ViewController in der 2. TabBar wechseln. Ich benutze einfach die Lösung im Obergeschoss:

tabBarController.selectedIndex = 2

Wenn Sie jedoch zur Startseite der 2. Registerkarte wechseln, ist der Inhalt unsichtbar. Und wenn ich debugge, viewDidAppear, viewWillAppear, viewDidLoad, wird keiner von ihnen aufgerufen. Meine Lösung besteht darin, den folgenden Code in den UITabBarController einzufügen:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}
Jin
quelle
0

Verwendung in AppDelegate.mDatei:

(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;

    }

}
Rakesh Singh
quelle
0

Wie Stuart Clarks Lösung, jedoch für Swift 3 und Verwendung der Wiederherstellungskennung, um die richtige Registerkarte zu finden:

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
}

Verwenden Sie es wie folgt ("Menschen" und "Roboter" müssen auch im Storyboard für einen bestimmten viewController und dessen Wiederherstellungs-ID festgelegt sein, oder verwenden Sie die Storyboard-ID und aktivieren Sie "Storyboard-ID verwenden" als Wiederherstellungs-ID):

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

Bitte beachten Sie, dass mein tabController hinter viewControllers auf viewController verweist. Ohne Navigationscontroller würde es so aussehen:

if controller.restorationIdentifier == id {
Json
quelle
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
quelle
1
Normalerweise ist es besser, eine Lösung zu erklären, als nur einige Zeilen anonymen Codes zu veröffentlichen. Sie können lesen, wie ich eine gute Antwort schreibe und auch vollständig codebasierte Antworten
erkläre