2015-11-20 18 views
18

Ho un controller di visualizzazione radice che non è impostato come classe personalizzata per nessuno dei miei controller di visualizzazione sullo storyboard. Invece, tutti i miei controller di vista stanno sottoclassi questa classe in questo modo.Rileva quando viene premuto un elemento della barra delle schede

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

} 

ma mi sembra di essere alle prese con fare qualcosa quando si preme un tabbaritem sul controller della vista che viene sottoclasse il RootViewController, cioè, il messaggio non viene stampato.

risposta

38

Non si desidera che la classe base del proprio controller di visualizzazione sia UITabBarDelegate. Se lo facessi, tutte le sottoclassi del controller di visualizzazione sarebbero delegate alla barra delle linguette. Quello che penso che si vuole fare è quello di estendere UITabBarController, qualcosa di simile:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate { 

allora, in quella classe, ignorare viewDidLoad e in là impostare la proprietà delegato di auto:

self.delegate = self 

Nota: Questo è l'impostazione del delegato del controller della barra delle schede. La barra delle schede ha il suo delegato (UITabBarDelegate), che gestisce il controller della barra delle linguette e non ti è permesso di cambiare.

Così, ora questa classe è sia un UITabBarDelegate (perché UITabBarController implementa quel protocollo), e UITabBarControllerDelegate, ed è possibile sostituire/implementare metodi quelle del delegato, se lo desideri, come ad esempio:

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

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

Sto indovinando probabilmente sei più interessato a quest'ultimo. Controlla la documentazione per vedere cosa forniscono ciascuno di questi delegati.

Ultima cosa, nello storyboard (supponendo che si stiano utilizzando gli storyboard), imposta la classe del controller della barra delle schede su MyTabBarController in Identity Inspector e sei pronto per partire.

+0

Grazie per la risposta a tutto tondo. Se diciamo che c'è un metodo nel mio ViewController che voglio implementare quando l'utente colpisce qualche tabbar, o dovrei trasformare il mio VC in TabBarDelegate, che hai citato correttamente renderà tutte le sottoclassi dei miei VC tabelegate, che non è utile a tutti. Altro modo se quello che hai menzionato. Ma poi mi resterebbero solo con l'utilizzo di protocolli o qualche altro modo per inviare messaggi al mio VC dal nuovo TabBarController se voglio che quel metodo nel VC sia implementato, non è vero? – Manganese

+1

@Manganese Si tratta di una decisione architettonica basata sulle vostre esigenze. Come con la maggior parte delle cose, ci saranno molti modi per implementare ciò che vuoi fare. Se puoi dare maggiori dettagli su ciò che stai cercando di fare, sarei felice di condividere i miei pensieri. Vuoi che ogni VC applichi il metodo a cui ti stai riferendo? I protocolli possono essere utili qui, ma altre opzioni sono probabilmente disponibili in base alle vostre esigenze. – mbeaty

+0

Ottimo, in pratica ho due barre di tabulazione: una è la mia VC principale e un'altra è VC delle impostazioni. Le impostazioni sono come azzeramento dei livelli di gioco, spegnimento/accensione dell'audio ecc. Il VC principale è dove ci si aspetta che l'utente sia la maggior parte delle volte, a meno che non voglia modificare alcune impostazioni. Voglio che il mio VC principale sappia dove è stata modificata una determinata impostazione. Quindi, ho creato una classe per memorizzare la proprietà type che cambia in modifica in Impostazioni Visualizza attributi. Da lì, utilizzo il risultato per configurare il mio VC principale, in modo che non appena l'utente naviga verso il VC principale, le impostazioni diventino effettive. – Manganese

23

Facendo in questo modo mi ha causato un errore Changing the delegate of a tab bar managed by a tab bar controller is not allowed

Questo è quello che ho fatto e che funzionato

  1. In te ViewController si eredita UITabBarControllerDelegate
  2. Set delegato in un viewDidLoad
  3. Aggiungi una funzione

Esempio:

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

estremamente piacevole! –

+0

didSelect metodo non chiamato. come può risolverlo –

+1

@ShahbazAkram nella viewDidLoad aggiungi riga: self.tabBarController? .delegate = self – Gulz

0

Ecco una versione di risposta di @ mbeaty con un po 'più di contesto. È adattato dal mio fuller answer here.

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

Impostare questo come la classe personalizzata del proprio controller Vista Tab in IB.

enter image description here

soluzione alternativa

  • Basta fare qualcosa nel metodo del controller della vista della scheda viewDidLoad. Vedi this answer.
Problemi correlati