Search code examples
iosswiftdelegatesuitabbarnavigationbar

Access Method in TabBarController from other class


i spend the last hours to fix this problem but nothing did helped. My LocationHelper Delegate looks like this:

func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
            print("not terminated")
            break
        case .authorizedWhenInUse, .authorizedAlways:
            NavigationBarController().checkLocationBasedElements(result: 1)

            print("auth okay")
            break
        case .restricted, .denied:
            NavigationBarController().checkLocationBasedElements(result: 2)
            print("auth denied")
            break
        }
    }

When the Authorization Status changes, i can see the print-outputs correctly on the console. My NavigationBarController.checkLocationBasedElements looks like this:

func checkLocationBasedElements(result: Int) -> Void{
        if(result == 2){
            print("checklocation: 2")
            tabBar.items?[1].isEnabled = false
            tabBar.items?[2].isEnabled = false
        }
        if(result == 1){
            //auth ok
            print("checklocation: 1")
            tabBar.items?[1].isEnabled = true
            tabBar.items?[2].isEnabled = true
        }

    }

When the User changes the auth-status to .authorizedWhenInUse the console gives this output:

checklocation: 1
auth okay

So it can be said that the methods get called correctly. But the tabBar do not change the isEnabled to true or false. I tried much things like putting the logic into the NavigationBarControllers' viewDidLoad or check the permission-status every time the app gets opened but this is not a very elegant solution I think so that i implemented the delegate. Do I have to instanciate the NavigationBarController otherwise like I have done it or what would you recommend?

Thanks in advance! Edit: NavigationBarController:

import UIKit

class NavigationBarController: UITabBarController {

    //let locationHelper = LocationHelper()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.


        let iconSize = CGSize(width: 35, height: 35)
        let iconUnselected = UIColor.white
        let iconSelected = UIColor.gray

        //Start
        tabBar.items?[0].title = "Start"
        tabBar.items?[0].setFAIcon(icon: .FAHome, size: iconSize, textColor: iconUnselected, backgroundColor: .clear, selectedTextColor: iconSelected, selectedBackgroundColor: .clear)

        //Live
        tabBar.items?[1].title = "Live"
        tabBar.items?[1].setFAIcon(icon: .FATachometer, size: iconSize, textColor: iconUnselected, backgroundColor: .clear, selectedTextColor: iconSelected, selectedBackgroundColor: .clear)

        //Messen
        tabBar.items?[2].title = "Messen"
        tabBar.items?[2].setFAIcon(icon: .FAClockO, size: iconSize, textColor: iconUnselected, backgroundColor: .clear, selectedTextColor: iconSelected, selectedBackgroundColor: .clear)

        //Ergebnisse
        tabBar.items?[3].title = "Ergebnisse"
        tabBar.items?[3].setFAIcon(icon: .FAWindowRestore, size: iconSize, textColor: iconUnselected, backgroundColor: .clear, selectedTextColor: iconSelected, selectedBackgroundColor: .clear)



        //Check GPS Permission
        //self.checkLocationBasedElements(result: LocationHelper.shared.checkStatus())


    }
    func checkLocationBasedElements(result: Int) -> Void{
        //look above

    }

Solution

  • For your current design, the quickest solution would be:

    1. Your LocationHelper should declare an instance of NavigationBarController

      class LocationHelper {
          //...
          weak var myTabBarController: NavigationBarController?
          //...
      }
      
    2. myTabBarController should be set once from NavigationBarController:

      class NavigationBarController: UITabBarController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view, typically from a nib.
      
              LocationHelper.shared.myTabBarController = self
      
              //...
          }
      
      }
      
    3. Your locationManager(_ manager:didChangeAuthorization:) should call

      myTabBarController?.checkLocationBasedElements(result:)
      

      instead of

      NavigationBarController().checkLocationBasedElements(result:)
      

      i.e.

      func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {
          switch status {
          case .notDetermined:
              print("not terminated")
          case .authorizedWhenInUse, .authorizedAlways:
              myTabBarController?.checkLocationBasedElements(result: 1)
      
              print("auth okay")
          case .restricted, .denied:
              myTabBarController?.checkLocationBasedElements(result: 2)
              print("auth denied")
          }
      }
      

    Basically when you do NavigationBarController().checkLocationBasedElements(result:) you are running checkLocationBasedElements(result:) on a new instance of NavigationBarController which is not the same as the one that's containing the tabs you see.