J'ai un contrôleur de vue racine qui n'est défini comme classe personnalisée pour aucun de mes contrôleurs de vue sur mon storyboard. Au lieu de cela, tous mes contrôleurs de vues sous-classent cette classe comme suit.
// 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 {
}
Mais je semble avoir du mal à faire quelque chose quand un tabbaritem est pressé sur le contrôleur de vue qui sous-classe le rootviewcontroller, c’est-à-dire que le message n’est pas imprimé.
Vous ne voulez pas que la classe de base de votre contrôleur de vue soit un UITabBarDelegate. Si vous deviez le faire, toutes les sous-classes de votre contrôleur de vue seraient des délégués de la barre d’onglet. Ce que je pense que vous voulez faire, c'est étendre UITabBarController, quelque chose comme ceci:
class MyTabBarController: UITabBarController, UITabBarControllerDelegate {
puis, dans cette classe, remplacez viewDidLoad et définissez-y la propriété delegate à self:
self.delegate = self
Remarque: Il s’agit de définir le délégué du contrôleur de la barre d’onglet. La barre d'onglets a son propre délégué (UITabBarDelegate), géré par le contrôleur de la barre d'onglets, et vous n'êtes pas autorisé à le modifier.
Donc, maintenant cette classe est à la fois une UITabBarDelegate (parce que UITabBarController implémente ce protocole), et UITabBarControllerDelegate, et vous pouvez remplacer/implémenter les méthodes de ce délégué, telles que:
// UITabBarDelegate
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
print("Selected item")
}
// UITabBarControllerDelegate
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
print("Selected view controller")
}
Je devine que vous êtes probablement plus intéressé par ce dernier. Consultez la documentation pour voir ce que chacun de ces délégués fournit.
Dernière chose, dans votre scénario (en supposant que vous utilisez des scénarios), définissez la classe de votre contrôleur de barre d'onglet sur MyTabBarController dans l'inspecteur d'identité, et le tour est joué.
Swift 3/4
// UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print("Selected item")
}
// UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
print("Selected view controller")
}
Faire ainsi m'a causé une erreur
Changer le délégué d'une barre d'onglets gérée par un contrôleur n'est pas autorisé
C'est ce que j'ai fait et c'est travaillé
ViewController
vous héritez UITabBarControllerDelegate
viewDidLoad
Exemple:
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
}
}
Voici une version de la réponse de @ mbeaty avec un peu plus de contexte. Il est adapté de mon réponse plus complète ici .
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) {
// ...
}
}
Définissez-la en tant que classe personnalisée de votre contrôleur de vue par onglet dans IB.
Solution alternative
viewDidLoad
du contrôleur de vue de l'onglet. Voir cette réponse .J'ai utilisé ce code, car j'ai besoin de savoir que le même contrôleur de vue est sélectionné.
import UIKit
protocol CustomTabBarControllerDelegate {
func onTabSelected(isTheSame: Bool)
}
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
(viewController as? CustomTabBarControllerDelegate)?.onTabSelected(isTheSame: selectedViewController == viewController)
return true
}
}
Premier onglet vue contoller
import UIKit
class Tab1ViewController: UIViewController, CustomTabBarControllerDelegate {
func onTabSelected(isTheSame: Bool) {
print("Tab1ViewController onTabSelected")
//do something
}
}
Deuxième onglet vue contoller
import UIKit
class Tab2ViewController: UIViewController, CustomTabBarControllerDelegate {
func onTabSelected(isTheSame: Bool) {
print("Tab2ViewController onTabSelected")
//do something
}
}
N'oubliez pas de définir CustomTabBarController en tant que classe personnalisée sur votre TabBarController dans votre storyboard et d'implémenter le protocole CustomTabBarControllerDelegate avec tous vos contrôleurs de vue par onglets.
Si vous utilisez UINavigationController, cela ne fonctionnera pas si UINavigationController n'est pas le point d'entrée du storyboard. Assurez-vous que vous avez une structure de storyboard comme ci-dessous.