web-dev-qa-db-fra.com

Détecter lorsqu'un élément de la barre de tabulation est activé

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é.

38
Tunds

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")
}
71
mbeaty

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é

  1. En vous ViewController vous héritez UITabBarControllerDelegate
  2. Définir un délégué dans un viewDidLoad
  3. Ajouter une fonction

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
   }

}
43
Gulz

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.

enter image description here

Solution alternative

  • Il suffit de faire quelque chose dans la méthode viewDidLoad du contrôleur de vue de l'onglet. Voir cette réponse .
6
Suragch

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.

The structure of storyboard

1
Zhebzhik Babich