2017-06-30 1 views
0

J'ai le code suivant que j'essaye de réaliser un "scroll to top" sur un UIViewcontroller et de "faire défiler jusqu'au début" sur un autre UIViewController.UITabBarControllerDelegate sur deux UIViewControllers séparés - Swift

Le premier circuit virtuel a une vue de table et le second circuit virtuel a une vue de collection.

-NearMeViewController- 
override func viewDidLoad() { 
     super.viewDidLoad() 
     self.tabBarController?.delegate = self 
     //.... 
} 
extension NearMeViewController: UITabBarControllerDelegate { 
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 
     let tabBarIndex = tabBarController.selectedIndex 
     if tabBarIndex == 0 { 
      self.nearMeTable.setContentOffset(CGPoint.zero, animated: true) 
     } 
    } 
} 

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

extension MapSearchViewController: UITabBarControllerDelegate { 
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 
     let tabBarIndex = tabBarController.selectedIndex 
     if tabBarIndex == 2 && requests.mapEventData.count > 0 { 
      self.resultsCollectionView?.scrollToItem(at: IndexPath(row: 0, section: 0), 
                at: .left, 
                animated: true) 
     } 
    } 
} 

Ils sont tous deux connectés à la même UITabBar bien sûr. Le problème est que lorsque j'ouvre l'application, et j'appuie sur le tabBarIndex 0 il défile vers le haut de la vue de la table.

Ensuite, je change VC et j'essaie d'appuyer sur le tabBarIndex 2, donc il me faut au premier élément de la vue de la collection.

Ensuite, je reviens au premier VC et quand j'essaie d'appuyer sur le tabBarIndex 0, la tableview ne fait pas défiler vers le haut (comme c'était le cas quand j'ai ouvert l'application pour la première fois).

Mais le second VC avec la vue de collection fonctionne bien.

Une idée de ce qui pourrait arriver?

Répondre

0

Il semble que vous vérifiez .selectedIndex de la tabBarController ... mais qui est l'indice de l'montrant actuellement onglet, pas l'onglet que vous êtes « sur votre chemin à. »

Plus probablement, vous souhaitez utiliser un code similaire à ceci:

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 

    if let vc = viewController as? MapSearchViewController { 
     // user tapped Map Search tab item 
    } 

    if let vc = viewController as? NearMeViewController { 
     // user tapped Near Me tab item 
    } 

} 

Edit: Voici un exemple simple, en utilisant un sous-classé UITabBarController.

Configurez votre storyboard comme d'habitude, créez des contrôleurs de vue et connectez-les en tant que «onglets», puis définissez la classe personnalisée du TabBarController sur MyTabBarController. Cet exemple de code sera (espérons-le) facile à suivre.

Un exemple runnable est à: https://github.com/DonMag/SWTabBarSubclass

// 
// TabBarSample.swift 
// 

import UIKit 

class FirstViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // all your normal setup stuff.... 
    } 

    func firstViewSpecific(_ aValue: Int) -> Void { 
     print("Passed value is:", aValue) 
     // do something with the passed value 
    } 

} 

class NearMeViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // all your normal setup stuff.... 
    } 

    func resetMe() -> Void { 
     print("resetMe() called in NearMeVC") 
     // do whatever you want, such as 
     self.nearMeTable.setContentOffset(CGPoint.zero, animated: true) 
    } 

} 

class MapSearchViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // all your normal setup stuff.... 
    } 

    func resetMe() -> Void { 
     print("resetMe() called in MapSearchVC") 
     // do whatever you want, such as 
     if requests.mapEventData.count > 0 { 
      self.resultsCollectionView?.scrollToItem(at: IndexPath(row: 0, section: 0), 
                at: .left, 
                animated: true) 
     } 
    } 

} 

class MyTabBarController: UITabBarController, UITabBarControllerDelegate { 

    var myValue = 0 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // make self the UITabBarControllerDelegate 
     self.delegate = self 
    } 

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { 

     if let vc = viewController as? FirstViewController { 
      myValue += 1 
      vc.firstViewSpecific(myValue) 
      return 
     } 

     if let vc = viewController as? NearMeViewController { 
      vc.resetMe() 
      return 
     } 

     if let vc = viewController as? MapSearchViewController { 
      vc.resetMe() 
      return 
     } 

    } 

} 
+0

et je devrais mettre ceci sur quel contrôleur de vue? –

+0

J'ai sous-classé 'UITabBarController' pour ce type de tâche ... Ou, créez une classe' NSObject, UITabBarControllerDelegate' séparée et l'assigner en tant que délégué ... Ou, vous pouvez le placer dans le contrôleur de vue du premier onglet. Je recommanderais le sous-classement. – DonMag

+0

Et si je sous-classe le 'UITabBarController' comment puis-je accéder à la tableview ou collectionview des autres vcs? –

1

viewDidLoad n'est pas appelé à chaque fois que le VC apparaît, mais une seule fois (ou quand il a été désallouée avant)

le délégué de vc 0 est réglé Une seule fois ... puis vc1 est chargé et défini comme délégué ... mais pas encore vc0.

Pour que cela fonctionne, définissez le délégué dans viewWillAppear.

Note

changer le délégué à plusieurs reprises pour cela est bizarre ... et la vérification de l'indice est au mieux fragile aller avec la solution de DonMag.

+0

vous avez un point à propos de 'viewDidLoad'! cela fonctionne avec 'viewDidAppear' mais je ne suis pas sûr de comprendre la réponse de @DonMag –