Detectar cuando se presiona un elemento de barra de pestañas


Tengo un controlador de vista raíz que no está configurado como la clase personalizada para ninguno de mis controladores de vista en mi guion gráfico. En su lugar, todos mis controladores de vista están subclasificando esta clase de esta manera.

// 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 {

}

Pero parece que estoy luchando con hacer algo cuando se presiona un tabbaritem en el controlador de vista que está subclasificando el rootviewcontroller, es decir, el mensaje no se está imprimiendo.

Author: Suragch, 2015-11-21

3 answers

No quieres que la clase base de tu controlador de vista sea una UITabBarDelegate. Si hiciera eso, todas las subclases de su controlador de vista serían delegados de la barra de pestañas. Lo que creo que quieres hacer es extender UITabBarController, algo como esto:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

Luego, en esa clase, sobrescribe viewDidLoad y allí establece la propiedad delegate en self:

self.delegate = self

Nota: Esto es configurar el delegado del controlador de la barra de pestañas. La barra de pestañas tiene su propio delegado (UITabBarDelegate), que el controlador de la barra de pestañas se administra, y no se le permite cambiar.

Así que, ahora esta clase es a la vez UITabBarDelegate (porque UITabBarController implementa ese protocolo), y UITabBarControllerDelegate, y puede anular / implementar los métodos de delegado como desee, tales como:

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

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

Supongo que probablemente estés más interesado en esto último. Echa un vistazo a la documentación para ver lo que cada uno de estos delegados proporcionan.

Lo último, en tu storyboard (suponiendo que eres usando storyboards), establezca la clase de su controlador de barra de pestañas en MyTabBarController en el Inspector de Identidad, y ya está listo.

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")
}
 51
Author: mbeaty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 13:47:01

Hacerlo de esta manera me causó un error

Cambiar el delegado de una barra de pestañas administrada por un controlador de barra de pestañas es no permitido

Esto es lo que hice y funcionó

  1. En ti ViewController heredas UITabBarControllerDelegate
  2. Establecer delegado en un viewDidLoad
  3. Añadir una función

Ejemplo:

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
   }

}
 28
Author: Gulz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-29 01:28:57

Aquí hay una versión de la respuesta de @mbeaty con un poco más de contexto. Está adaptado de mi respuesta más completa aquí.

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) {
        // ...
    }
}

Establezca esto como la clase Personalizada de su Controlador de Vista de pestañas en IB.

introduzca la descripción de la imagen aquí

Solución Alternativa

  • Simplemente haga algo en el método viewDidLoad del controlador de vista de la pestaña. Ver esta respuesta.
 3
Author: Suragch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-18 04:00:37