-2

I have been programming without storyboards in swift. With doing so, I thought it would be interesting to add in a tab bar to my view controller. I have been researching different ways to try this, However, I'm yet to find an answer that suitably fits my application.

    //This is my app delegate

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()
    let mainController = UINavigationController(rootViewController:       mainViewController())
    let loginController = UINavigationController(rootViewController: LoginController())

    FirebaseApp.configure()
    userIsloggedIn = defaults.bool(forKey: "User is Logged In")
    if userIsloggedIn == true {
      window?.rootViewController = mainController
    } else {
       window?.rootViewController = loginController
    }
    UINavigationBar.appearance().barTintColor = GREEN_Theme
    return true
}

//this is my TabBar controller, which is placed over my "mainViewController"

class CustomTabBarController: UITabBarController {

override func viewDidLoad() {
    super.viewDidLoad()

    self.tabBar.barTintColor = GREEN_Theme
    self.tabBar.isTranslucent = true
    self.tabBar.tintColor = .white

    let mainController = UINavigationController(rootViewController: mainViewController())
    mainController.tabBarItem.title = "Find Jobs"
    mainController.tabBarItem.image = UIImage(named: "job-search")
    let settingsController = UINavigationController(rootViewController: settingsViewController())
    settingsController.tabBarItem.title = "Settings"
    settingsController.tabBarItem.image = UIImage(named: "settings")
    let notificationsController = UINavigationController(rootViewController: notificationsViewController())
    notificationsController.tabBarItem.title = "Notifications"
    notificationsController.tabBarItem.image = UIImage(named: "notification")
    let messagesController = UINavigationController(rootViewController: messagesViewController())
    messagesController.tabBarItem.title = "Messages"
    messagesController.tabBarItem.image = UIImage(named: "chat")
    let historyController = UINavigationController(rootViewController: jobhistoryViewController())
    historyController.tabBarItem.title = "Job History"
    historyController.tabBarItem.image = UIImage(named: "medical-history")


    viewControllers = [historyController, notificationsController, mainController, messagesController, settingsController]
    return

}
}

// lastly, this is my mainViewController

import UIKit

import Foundation import Firebase import MapKit import GoogleMaps import CoreLocation

class mainViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

private var locationManager = CLLocationManager()
var mapView = GMSMapView()
var camera = GMSCameraPosition()
var sidebarView: SidebarView!
var blackScreen: UIView!

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
    let lastLocation = locations[locations.count-1]
    if lastLocation.horizontalAccuracy>0{
        locationManager.stopUpdatingLocation()
        let latitude = lastLocation.coordinate.latitude
        let longitude = lastLocation.coordinate.longitude

    }
}

override func viewDidLoad() {
    super.viewDidLoad()



    let btnMenu = UIBarButtonItem(image: #imageLiteral(resourceName: "menu-button-of-three-horizontal-lines"), style: .plain, target: self, action: #selector(btnMenuAction))
    btnMenu.tintColor=UIColor(red: 54/255, green: 55/255, blue: 56/255, alpha: 1.0)
    self.navigationItem.leftBarButtonItem = btnMenu

    sidebarView=SidebarView(frame: CGRect(x: 0, y: 0, width: 0, height: self.view.frame.height))
    sidebarView.delegate=self
    sidebarView.layer.zPosition=100
    self.view.isUserInteractionEnabled=true
    self.navigationController?.view.addSubview(sidebarView)

    blackScreen=UIView(frame: self.view.bounds)
    blackScreen.backgroundColor=UIColor(white: 0, alpha: 0.5)
    blackScreen.isHidden=true
    self.navigationController?.view.addSubview(blackScreen)
    blackScreen.layer.zPosition=99
    let tapGestRecognizer = UITapGestureRecognizer(target: self, action: #selector(blackScreenTapAction(sender:)))
    blackScreen.addGestureRecognizer(tapGestRecognizer)
}

@objc func btnMenuAction() {
    blackScreen.isHidden=false
    UIView.animate(withDuration: 0.3, animations: {
        self.sidebarView.frame=CGRect(x: 0, y: 0, width: 250, height: self.sidebarView.frame.height)
    }) { (complete) in
        self.blackScreen.frame=CGRect(x: self.sidebarView.frame.width, y: 0, width: self.view.frame.width-self.sidebarView.frame.width, height: self.view.bounds.height+100)
    }
}

@objc func blackScreenTapAction(sender: UITapGestureRecognizer) {
    blackScreen.isHidden=true
    blackScreen.frame=self.view.bounds
    UIView.animate(withDuration: 0.3) {
        self.sidebarView.frame=CGRect(x: 0, y: 0, width: 0, height: self.sidebarView.frame.height)
    }
}

}

extension mainViewController: SidebarViewDelegate {
    func sidebarDidSelectRow(row: Row) {
        blackScreen.isHidden=true
        blackScreen.frame=self.view.bounds
        UIView.animate(withDuration: 0.3) {
            self.sidebarView.frame=CGRect(x: 0, y: 0, width: 0, height: self.sidebarView.frame.height)
        }
        switch row {
        case .editProfile:
            let vc=EditProfileVC()
            self.navigationController?.pushViewController(vc, animated: true)
        case .reviews:
            print("Reviews")
        case .contact:
            print("Contact")
        case .payment:
            print("Payment")
        case .share:
            print("Share")
        case .help:
            print("Help")
        case .signOut:
            print("Sign out")
            let SignOutvc=signoutVC()
            self.navigationController?.pushViewController(SignOutvc, animated: true)
        case .none:
            break
        }
        GMSServices.provideAPIKey("AIzaSyBDOLisA3c-wDTbkbSssAxEb3iLw7Y5vHo")
        let camera = GMSCameraPosition.camera(withLatitude: 40.001850, longitude: -83.019405, zoom: 17)
        let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        self.view = mapView
        mapView.isMyLocationEnabled = true



    let currentLocation = CLLocationCoordinate2DMake(40.001850, -83.019405)
    let marker = GMSMarker(position: currentLocation)
    marker.snippet = "Current Location"
    marker.map = mapView
    self.mapView.addSubview(mapView)


    func getLocation(){
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()

    }

    navigationController?.navigationBar.prefersLargeTitles = false
    navigationItem.title = "Welcome To Odd Jobs"
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white, NSAttributedStringKey.font: UIFont.systemFont(ofSize: 25)]
}
        func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
            reverseGeocodeCoordinate(position.target) // sending data when the mapView is not moved or pinched by the finger //
        }

        func reverseGeocodeCoordinate(_ coordinate: CLLocationCoordinate2D) {
            let geocoder = GMSGeocoder()
            geocoder.reverseGeocodeCoordinate(coordinate) { response, error in
                guard let address = response?.firstResult(), let _ = address.lines else {
                    return
    }
   }
  }
}

My goal is to combine the customTabBarViewController, with my main View controller. If I run my application, it has me set to the customTabBar, which overlaps my mainVC. If I log out and try to Login, I'm placed at a default tabBar screen with a black background.

Zach Wilcox
  • 39
  • 1
  • 7

1 Answers1

0

It's not clear what your issue is. You say you don't want to add the UITabBarController as the rootViewController because of your login, but then in your example you give the solution which is to condition which view controller to set based on being logged in. (Along with calling that condition again after logging in.)

However to answer your question directly, if you want to add a UITabBarController to a UIViewController you should use containment.

// Adding a contained view controller
addChildViewController(tabBarController)
view.addSubview(tabBarController.view)
tabBarController.didMove(toParentViewController: self)

// Removing a contained view controller
tabBarController.willMove(toParentViewController: nil)
tabBarController.view.removeFromSuperview()
tabBarController.removeFromParentViewController()
cnotethegr8
  • 7,342
  • 8
  • 68
  • 104
  • Sorry for the misleading question! I’m fine adding it ass the rootview however I’m afraid I will make my app crash without knowing how to fix the problem! – Zach Wilcox Jun 14 '18 at 05:34
  • You can change the root view, it wont crash. If you go down that route, you can also use an animation for a more natural change. https://stackoverflow.com/questions/41144523/swap-rootviewcontroller-with-animation – cnotethegr8 Jun 14 '18 at 05:37
  • I have my main view controller and login view controller both set as my main root. With that cause conflict? – Zach Wilcox Jun 14 '18 at 05:38
  • 1
    Only one can be set at a time. Whichever you currently want should be the most recent one set. Also don't be scared of potential crashes. A. Trying things out is the best way to learn. B. You'll save time from having to ask online. C. Your phone won't explode! – cnotethegr8 Jun 14 '18 at 05:40