2015-11-20 12 views
18

Ich habe einen Stammansicht-Controller, der nicht als benutzerdefinierte Klasse für einen meiner View-Controller in meinem Storyboard festgelegt ist. Stattdessen bilden alle meine View-Controller diese Klasse ab.Erkennen, wenn ein Registerkartenelement gedrückt wird

// RootViewController 
class RootViewController: UIViewController, UITabBarDelegate { 

    // This is not getting executed on any of the view controllers 
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) { 
     print("ddd") 
    } 
} 

// Subclassing it 
class TopStoriesViewController: RootViewController { 

} 

Aber ich scheine mit zu kämpfen, etwas zu tun, wenn ein tabbaritem auf dem View-Controller gedrückt wird, die die RootViewController wird Subklassen, das heißt, wird die Nachricht nicht gedruckt wird.

Antwort

38

Sie möchten nicht, dass die Basisklasse Ihres View-Controllers ein UITabBarDelegate ist. Wenn Sie dies tun würden, wären alle Ihre View-Controller-Unterklassen Tab-Bar-Delegaten. Was ich denke, Sie tun möchten, ist UITabBarController, so etwas zu erweitern:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate { 

dann, in dieser Klasse, außer Kraft setzen viewDidLoad und dort den Delegaten Eigenschaft auf Selbst gesetzt:

self.delegate = self 

Hinweis: Dies setzt den Tab-Controller-Delegaten. Die Registerkartenleiste hat ihren eigenen Delegaten (UITabBarDelegate), den der Tab-Leiste-Controller verwaltet, und Sie können nicht ändern.

So, jetzt diese Klasse ist sowohl ein UITabBarDelegate (weil UITabBarController implementiert dieses Protokoll) und UITabBarControllerDelegate, und Sie können diejenigen Delegierten Methoden überschreiben/implementieren, wie gewünscht, wie zum Beispiel:

// UITabBarDelegate 
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) { 
    print("Selected item") 
} 

// UITabBarControllerDelegate 
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) { 
    print("Selected view controller") 
} 

Ich vermute Sie interessieren sich wahrscheinlich eher für Letzteres. In der Dokumentation finden Sie Informationen zu den einzelnen Delegierten.

Als Letztes, in Ihrem Storyboard (vorausgesetzt, Sie verwenden Storyboards), setzen Sie die Klasse Ihres Tab-Bar-Controllers im Identity Inspector auf MyTabBarController, und Sie können loslegen.

+0

Danke für die runde Antwort. Wenn ich sagen möchte, dass es eine Methode in meinem ViewController gibt, die ich implementieren möchte, wenn der Benutzer eine Tab-Leiste anschlägt, müsste ich entweder VC in TabBarDelegate umwandeln, was Sie alle Unterklassen meiner VC tabbardelegates korrekt darstellen würden, was nicht sinnvoll ist alle. Andere Art und Weise, wenn das, was Sie erwähnt haben. Aber dann wäre ich nur mit der Verwendung von Protokollen oder einer anderen Möglichkeit zum Senden von Nachrichten an meine VC von neuem TabBarController übrig, wenn ich möchte, dass diese Methode in der VC implementiert wird, nicht wahr? – Manganese

+1

@Manganese Dies ist eine architektonische Entscheidung, die auf Ihren Anforderungen basiert. Wie bei den meisten Dingen gibt es mehrere Möglichkeiten, um das zu implementieren, was Sie tun möchten. Wenn Sie genauer erklären können, was Sie vorhaben, teile ich Ihnen gerne meine Gedanken mit. Möchten Sie, dass jede VC die Methode implementiert, auf die Sie sich beziehen? Protokolle können hier nützlich sein, aber andere Optionen sind wahrscheinlich basierend auf Ihren Anforderungen verfügbar. – mbeaty

+0

Großartig, im Grunde habe ich zwei Tab-Bars - eine ist meine Haupt-VC und eine andere ist Einstellungen VC. Die Einstellungen sind wie das Zurücksetzen der Spielstufen, Audio aus/ein usw. Der Haupt-VC ist, wo der Benutzer die meiste Zeit erwartet wird, es sei denn, er/sie möchte einige Einstellungen ändern. Ich möchte, dass mein Haupt-VC weiß, wo eine bestimmte Einstellung geändert wurde. Daher habe ich eine Klasse zum Speichern der Typeigenschaft erstellt, die sich in den Einstellungen der Ansichtsattribute ändert. Von dort aus verwende ich das Ergebnis, um meinen Haupt-VC zu konfigurieren, so dass die Einstellungen wirksam werden, sobald der Benutzer zum Haupt-VC navigiert. – Manganese

23

es auf diese Weise tun, verursacht mir ein Fehler Changing the delegate of a tab bar managed by a tab bar controller is not allowed

Das ist, was ich tat und es arbeitete

  1. In Sie ViewController Sie UITabBarControllerDelegate
  2. Set Delegat in einem viewDidLoad
  3. erben Fügen Sie eine Funktion
hinzu

Beispiel:

class MyClass: UIViewController, UITabBarControllerDelegate { 

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 
     let tabBarIndex = tabBarController.selectedIndex 
     if tabBarIndex == 0 { 
      //do your stuff 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.tabBarController?.delegate = self 
    } 

} 
+0

Extrem schön! –

+0

didSelect-Methode nicht aufgerufen. wie kann es gelöst werden. –

+1

@ShahbazAkram in Ihrer SichtDidLoad Zeile hinzufügen: self.tabBarController? .delegate = self – Gulz

0

Hier ist eine Version der Antwort des @ mbeaty mit ein wenig mehr Kontext. Es ist von meiner fuller answer here angepasst.

import UIKit 

class MyTabBarController: UITabBarController, UITabBarControllerDelegate { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // tell our UITabBarController subclass to handle its own delegate methods 
     self.delegate = self 
    } 

    // called whenever a tab button is tapped 
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 

     if let firstVC = viewController as? FirstViewController { 
      firstVC.doSomeAction() 
     } 

     if viewController is FirstViewController { 
      print("First tab") 
     } else if viewController is SecondViewController { 
      print("Second tab") 
     } 
    } 

    // alternate method if you need the tab bar item 
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { 
     // ... 
    } 
} 

Legen Sie dies als benutzerdefinierte Klasse Ihres Tab View Controller in IB fest.

enter image description here

Alternative Lösung

  • tun einfach etwas in der viewDidLoad Methode des View-Controller-Tab. Siehe this answer.
Verwandte Themen