4

In my project i have three tabBar item home, notification and profile. And side menu controller has home, bookings, profile and logout. Side bar menu controller was done by using SWRevealViewController cocopods.

When i navigating side bar menu to home tab bar index was selected correctly and navigating properly. While navigating from bookings it navigates properly but again navigating home app gets crashed. And console output says Could not cast value of type 'UINavigationController' (0x10ef79420) to 'UITabBarController' (0x10ef79970).

Since bookings controller is custom view controller and remaining are tab bar controller. And when navigating to booking screen view controller tab bar should be hide and user tap again menu button and navigating to home or any other controller.

And crashed due to booking controller does not has tab bar index. So how can navigate without crash to custom controller and tabbar controller with selected index item.

Here is my screenshot:

bookings screen controller menu controller where swrevealviewcontroller used

My storyboard screenshot:

enter image description here

Here is the code which i have tried:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    //        tableView.deselectRow(at: indexPath, animated: true)

    let row = indexPath.row

    if row == 0{


        let tabBarController = revealViewController().frontViewController as! UITabBarController


        let storyboard = UIStoryboard(name: "Home", bundle: nil)

        let obj = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController

        let navController = UINavigationController.init(rootViewController: obj)
        tabBarController.selectedIndex = (indexPath as NSIndexPath).row
        tabBarController.tabBar.isHidden = false
        self.revealViewController().pushFrontViewController(tabBarController, animated: true)



    } else if row == 1{

        let tabBarController = revealViewController().frontViewController as! UITabBarController

        let storyboard = UIStoryboard(name: "Bookings", bundle: nil)
        let obj = storyboard.instantiateViewController(withIdentifier: "BookingsViewController") as! BookingsViewController
        let navController = UINavigationController.init(rootViewController: obj)
    //            tabBarController.selectedIndex = 1
    //            tabBarController.tabBar.isHidden = false
        self.revealViewController().pushFrontViewController(navController, animated: true)



    } else if row == 2 {

        let tabBarController = revealViewController().frontViewController as! UITabBarController

        let storyboard = UIStoryboard(name: "Profile", bundle: nil)
        let obj = storyboard.instantiateViewController(withIdentifier: "profileViewController") as! profileViewController
        let navController = UINavigationController.init(rootViewController: obj)
        tabBarController.selectedIndex = (indexPath as NSIndexPath).row
        tabBarController.tabBar.isHidden = false
        self.revealViewController().pushFrontViewController(tabBarController, animated: true)


    } else if row == 3 {
        print(indexPath)
        // Log out user from Firebase
        AuthService.signOut(onSuccess: {
            // Present the Sign In VC
     //                PrefsManager.sharedinstance.logoutprefences()
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let signInVC = storyboard.instantiateViewController(withIdentifier: "signInViewController")
                        self.present(signInVC, animated: true)

      //                self.navigationController?.pushViewController(signInVC, animated: true)

        }) { (errorMessage) in

            ProgressHUD.showError(errorMessage)

        }



    }


}
Lorenzo
  • 3,293
  • 4
  • 29
  • 56
PvDev
  • 791
  • 21
  • 67
  • Do you need `TabBar` in `Home` section only ? – VRAwesome Aug 06 '18 at 09:42
  • @VRAwesome yes i need tabBar in home and profile screens not in booking screen – PvDev Aug 06 '18 at 10:40
  • The possible line of concern is `revealViewController().frontViewController as! UITabBarController`. It seems as if `revealViewController().frontViewController` could possibly be the navigation controller as shown in your last screenshot. To help you debug, try printing the type of `revealViewController().frontViewController`, perhaps the frontViewController is not the controller you were expecting? – Schemetrical Aug 06 '18 at 15:57

1 Answers1

5

Here is Working Code of SWRevealViewController with UINavigationController and UITabBarController (Swift 4)

Your Storyborad it will be like this you not directly assign UITabBarController to revealViewController().frontViewController need to Use Like this.

enter image description here

Code of MenuViewController Like this

import UIKit

class menuViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

@IBOutlet weak var tblTableView: UITableView!
@IBOutlet weak var imgProfile: UIImageView!

var ManuNameArray:Array = [String]()
var iconArray:Array = [UIImage]()

override func viewDidLoad() {
    super.viewDidLoad()
    ManuNameArray = ["Home","Booking","Profile","Logout"]
    iconArray = [UIImage(named:"home")!,UIImage(named:"message")!,UIImage(named:"map")!,UIImage(named:"setting")!]

    imgProfile.layer.borderWidth = 2
    imgProfile.layer.borderColor = UIColor.green.cgColor
    imgProfile.layer.cornerRadius = 50

    imgProfile.layer.masksToBounds = false
    imgProfile.clipsToBounds = true 
    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return ManuNameArray.count

}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MenuCell", for: indexPath) as! MenuCell

    cell.lblMenuname.text! = ManuNameArray[indexPath.row]
    cell.imgIcon.image = iconArray[indexPath.row]

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let revealviewcontroller:SWRevealViewController = self.revealViewController()

    let cell:MenuCell = tableView.cellForRow(at: indexPath) as! MenuCell
    print(cell.lblMenuname.text!)

    if cell.lblMenuname.text! == "Home"
    {
        print("Home Tapped")

        let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

        // Here TabbarController is StoryboardID of UITabBarController
        if let tabBarController = mainstoryboard.instantiateViewController(withIdentifier: "TabbarController") as? UITabBarController{

            tabBarController.selectedIndex = 0
            revealviewcontroller.pushFrontViewController(tabBarController, animated: true)
        }
    }
    if cell.lblMenuname.text! == "Booking"
    {
        print("message Tapped")

        let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let newViewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "BookingViewController") as! BookingViewController
        let newFrontController = UINavigationController.init(rootViewController: newViewcontroller)

        revealviewcontroller.pushFrontViewController(newFrontController, animated: true)
    }
    if cell.lblMenuname.text! == "Profile"
    {
        let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

        if let tabBarController = mainstoryboard.instantiateViewController(withIdentifier: "TabbarController") as? UITabBarController{

            tabBarController.selectedIndex = 2
            revealviewcontroller.pushFrontViewController(tabBarController, animated: true)
        }
    }
    if cell.lblMenuname.text! == "Logout"
    {
       print("Logout Tapped")
    }
}
}

Code for Other Remaining ViewControllers Same as Following for All Home, Notification, Profile and Booking

import UIKit

class ProfileViewController: UIViewController {

@IBOutlet weak var btnMenuButton: UIBarButtonItem!

override func viewDidLoad() {
    super.viewDidLoad()

    if revealViewController() != nil {

        btnMenuButton.target = revealViewController()
        btnMenuButton.action = #selector(SWRevealViewController.revealToggle(_:))

        view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
    }

  }
}

Your Output :

enter image description here enter image description here

Nikunj Kumbhani
  • 3,758
  • 2
  • 26
  • 51
  • Awesome!! you saved my time.. Thanks for answering – PvDev Aug 07 '18 at 12:27
  • hey i have another doubt, not in this question. Another one firebase email update in swift – PvDev Aug 07 '18 at 12:48
  • @PvDev you want to update email only or email & password both? – Nikunj Kumbhani Aug 07 '18 at 12:54
  • only email not the password here is the code i tried: https://drive.google.com/file/d/1ZQtzvdU_NngUeyNGmt1wgOpRIDDELcZ3/view?usp=sharing – PvDev Aug 07 '18 at 12:57
  • error which i am getting in console is imageData:::czsm imageData:::czsm10@gmail.com imageData:::Optional(0) Error writing document: Optional(Error Domain=FIRAuthErrorDomain Code=17014 "This operation is sensitive and requires recent authentication. Log in again before retrying this request." UserInfo={NSLocalizedDescription=This operation is sensitive and requires recent authentication. Log in again before retrying this request., error_name=ERROR_REQUIRES_RECENT_LOGIN}) – PvDev Aug 07 '18 at 12:58
  • @PvDev **Check it Faced the Same Problem Like you** https://stackoverflow.com/a/38917910/10150796 – Nikunj Kumbhani Aug 07 '18 at 13:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/177572/discussion-between-nikunj-kumbhani-and-pvdev). – Nikunj Kumbhani Aug 07 '18 at 13:05