Minitour / AZTabBarController

A custom tab bar controller for iOS written in Swift 4.2
MIT License
348 stars 65 forks source link

how to push a new view controller after change selectedIndex #63

Closed frank61003 closed 4 years ago

frank61003 commented 4 years ago

I have six tabItem view controller, each child view controller has own a navigation controller itself. I have a problem to push a new view controller after change the selectedIndex.

//the viewcontroller I want to push let vc = self.storyboard?.instantiateViewController(withIdentifier: "CreateArticleViewController") as! CreateArticleViewController self.currentTabBar?.setIndex(3, animated: true) // Below code doesn't work self.navigationController?.pushViewController(vc, animated: true) self.currentnavigationController?.pushViewController(vc, animated: true)

tabcontroller -> Navigation 1 -> A1 -> A2
-> Navigation 2 -> B1 -> B2 -> B3 -> B4 -> Navigation 3 -> C1 -> C2 -> C3 -> C4 -> Navigation 4 -> D1 -> D2 -> D3 -> D4 -> Navigation 5 -> E1 -> E2 -> E3 -> Navigation 6 -> F1 -> F2 -> F3

For example, when I in A1, how do I change the index and push the view controller to D3? I also want my tabbar be more transparent. I can change background color perfectly but alpha doesn't work. How to set the AZTabBarController alpha?

Minitour commented 4 years ago

@frank61003

From what I read, you are trying to push the view controller on the navigation controller of your main controller. That navigation controller is probably nil.

What you want to do is get a reference to the controller from which you want to push. (Navigation 4).

This means you'll need to maintain a reference to that controller.

// assuming this is your main view controller
class ViewController: UIViewController {
    var tabBar: AZTabBarController!
    weak var nav4controller: UINavigationController?

    func viewDidLoad() {
         ...
         let myNavController4 = ... // nav init here
         // update the reference
          self.nav4controller = myNavController4
         self.tabBar.setViewController(myNavController4, atIndex: 3)
    }

    func pushArticleView() {
         let articleVc = ...
         self.nav4controller?.pushViewController(articleVc, animated: true)
    }
}

As for your second question about alpha: try to use the buttonsBackgroundColor property with a UIColor that has an alpha that is not 1.0

frank61003 commented 4 years ago

@Minitour

Thanks for your response. I have try to use your function. But what I mean is when I in ViewController A2 (not main ViewController(var tabBar in main ViewController)) and want to change my view controller to D3 by tapping a button? Should I use delegate or let my function public so my function can been called by other view controllers? I have a snapshot for my storyboard below. https://imgur.com/a/X860m7p

Although I change the alpha. It is still can't seen my viewController background Image(which should be blue) https://imgur.com/LjJbJj7

tabController.selectedColor = #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1)
tabController.selectionIndicatorHeight = 2
tabController.selectionIndicatorColor = #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1)
tabController.buttonsBackgroundColor = #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 0.2497056935)
tabController.tabBarHeight = 50

Really thanks for your help.

Minitour commented 4 years ago

If i understand you correctly, you want to switch the selected tab from within one of the controllers?

You can use try this in A2:

self.currentTabBar?.setIndex(4)

As for the alpha, I just remembered that the controllers are set above the tab bar, so it’s never gonna be underneath it. If you want you can try and hide the bar as an alternative or modify the source code to change that.

frank61003 commented 4 years ago

Hi I know that self.currentTabBar?.setIndex(4) can change to the forth tab first View. But if it is possible to push a second view after changing the selectedIndex in one action? The effect I want is change to forth tab second view after tapping a button. Thanks for your help!

frank61003 commented 4 years ago

Hi Can I use selectedViewController to change selected by original tabbar controller? Thank you. let vc = self.storyboard?.instantiateViewController(withIdentifier: "CreateArticleViewController") as! CreateArticleViewController self.tabBarController?.selectedViewController = vc

Minitour commented 4 years ago

I think I understand what you want to do. I have a solution, that may not be as elegant, but would do the job.

Store a reference to your navigation controller (like I mentioned earlier). Then when you need to access it, from A2 do the following:

func onArticleView() {
      // replace `as? ViewController` with the class that holds the tabbar
      let mainViewController = self.currentTabBar?.parentController as? ViewController

      guard let navigationController4 = mainViewController?.nav4controller else { return }

      let articleVc = ...
      self.navigationController4.pushViewController(articleVc, animated: true)

      self.currentTabBar?.setIndex(4)
}

This should get what you are trying to achieve.

frank61003 commented 4 years ago

Hi @Minitour,

I try the function that you mentioned, I can only find self.currentTabBar?.parent instead of self.currentTabBar?.parentController. But it works well so I can change my view by tapping a button. I also read your code and try another way to do the same effect. I change the variable controllers from fileprivate to public in AZTabBarController.swift and use the function below. Can you please tell me which way you prefer better? Maybe my way may cause some error that I don't image.

func tapPost() {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "CreateArticleViewController") as! CreateArticleViewController
        self.currentTabBar!.setIndex(3, animated: true)
        let dNav = self.currentTabBar!.controllers[3] as! UINavigationController
        dNav.pushViewController(vc, animated: true)
}

And if I want to bring some data after tapping the button, can I make a segue and use the prepare function to complete this action? Thank you.

Minitour commented 4 years ago

@frank61003 What you did is fine, but keep in mind, everytime you will call pod update you'll have to update the code again and change the access modifier from fileprivate to public or open.

My suggestion, while more complicated, require no code change to the framework.

Finally to answer your last question, Since the transitions are through navigation controllers no seques are required. If you want to transfer data from the initiating controller to the new Create Article Controller you should use the instance you created:

func tapPost() {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "CreateArticleViewController") as! CreateArticleViewController
        vc.myDataProperty = x
        vc.anotherProperty = y
        self.currentTabBar!.setIndex(3, animated: true)
        let dNav = self.currentTabBar!.controllers[3] as! UINavigationController
        dNav.pushViewController(vc, animated: true)
}
frank61003 commented 4 years ago

Hi Minitour,        Thanks for your kindly response. When I use the function to push new viewcontroller, is some way to let me know which viewcontroller is on the stack top? Now everytime I tap the button, it push a new viewcontroller. I use navigationController.viewControllers.count to know if there already has the viewcontroller that I want to push. May I use navigationController.topViewController == CreateArticleViewController to do the same effect?

@objc func onArticleView() {

          

          let mainViewController = self.currentTabBar?.parent as? SixItemTabbarViewController

          guard let navigationController3 = mainViewController?.myChildViewController3 else { return }                       if navigationController3.viewControllers.count == 2{                 var articleVc = navigationController3.topViewController as! CreateArticleViewController

                articleVc.judgeNumber = 1

                self.currentTabBar?.setIndex(3)

                return             }

         let articleVc = self.storyboard?.instantiateViewController(withIdentifier: "CreateArticleViewController") as! CreateArticleViewController

          navigationController3.pushViewController(articleVc, animated: true)

          self.currentTabBar?.setIndex(3)

    }

在 2020年4月7日 星期二 上午07:48:15 [GMT+8], Antonio Zaitoun<notifications@github.com> 寫道:  

Closed #63.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.