CosmicMind / Material

A UI/UX framework for creating beautiful applications.
http://cosmicmind.com
MIT License
11.99k stars 1.26k forks source link

I can't see the tab bar in this sample project. #1144

Closed manas-somoy closed 6 years ago

manas-somoy commented 6 years ago

BottomNavigationController.zip

Tabbar doesn't show up. Depthpreset not working.

Another thing I noticed that if viewdidload is implemented prepare is not called. I don't understand why. May be I'm missing something. I am using storyboard.

daniel-jonathan commented 6 years ago

Either @OrkhanAlikhanov or myself will help you shortly.

OrkhanAlikhanov commented 6 years ago

@CHONUMAN We investigated the issue, with help of @danieldahan, it turned out that the sample is actually setting tabItem instead of tabBarItem.

tabItem is used by TabsController, whereas BottomNavigationController uses tabBarItem. So, you should change all tabItem into tabBarItem and the sample will work as it's meant to be :)

Also, when you override viewDidLoad() make sure that you call super.viewDidLoad() otherwise prepare() method will not be called. Thank you!

daniel-jonathan commented 6 years ago

Thank you!

manas-somoy commented 6 years ago

hello @OrkhanAlikhanov. thanks for the help. the tabbar depthpreset and heightpreset won't set from the AppBottomNavigationController subclass.

class AppBottomNavigationController: BottomNavigationController {

  open override func prepare() {
        super.prepare()
        prepareTabBar()
  }

    private func prepareTabBar() {
        tabBar.depthPreset = .none //Does nothing
        tabBar.dividerColor = Color.grey.lighten2 //Does nothing
        tabBar.tintColor = UIColor.black //Does nothing
    }
}
daniel-jonathan commented 6 years ago

@CHONUMAN Tomorrow we will take another look. This seems weird. Thank you for sharing this with us.

OrkhanAlikhanov commented 6 years ago

I confirm that dividerColor and tintColor are working, but heightPreset don't.

As for depthPreset, it creates shadow below of the view. Since the tabBar is already at the bottomest place we don't see any shadow at all. To see shadow, we need to make it point upwards.

tabBar.depthPreset = .depth5
tabBar.layer.shadowOffset.height *= -1 // flip direction

We decided to make depthPreset directional. So to cast shadow above of a view, you will do:

tabBar.depthPreset = .above(.depth5)

We will also add support for heightPreset. Thank you!

manas-somoy commented 6 years ago

Hello, @OrkhanAlikhanov . I need help with another thing. I'm adding child ViewControllers of the BottomNavigationController in the app delegate.

let homeVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let contestVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ContestViewController") as! ContestViewController 
let appTabVC = AppTabViewController(viewControllers: [HomeNavigationController(rootViewController: homeVc), ContestNavigationViewController(rootViewController: contestVC)])  
let drawerMenuVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DrawerViewController")
let drawerControllerVC = AppNavigationDrawerViewController(rootViewController: appTabVC, leftViewController: nil, rightViewController: drawerMenuVC)

window?.rootViewController = drawerControllerVC

But when I run the app the second tabbaritem does not get loaded. I'm setting the tab bar item in the ContestNavigationViewController. Convenience init() is used in the sample project. I tried to follow it but it's not working. screen shot 2018-09-11 at 10 10 37 pm

But the tabbaritem is there. when i click it it gets loaded but the image offset gets all wierd. screen shot 2018-09-11 at 10 12 14 pm

The code in the ContestNavigationController is like this -

class ContestNavigationViewController: NavigationController {

    convenience init() {
        self.init(nibName: nil, bundle: nil)
        preparetabBarItem()
    }

    override func prepare() {
        guard let v = navigationBar as? NavigationBar else {
            return
        }

        v.depthPreset = .none
        v.dividerColor = Color.grey.lighten1

        preparetabBarItem()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.tintColor = Color.red.accent4
        tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -4)

        prepare()
    }

    override var preferredStatusBarStyle: UIStatusBarStyle { return self.childViewControllers.last?.preferredStatusBarStyle ?? .default }

}

extension ContestNavigationViewController {
    fileprivate func preparetabBarItem() {
        tabBarItem.image = UIImage(named: "tabHomeIcon")?.tint(with: Color.grey.base)
        tabBarItem.title = "HOME"
        tabBarItem.selectedImage = UIImage(named: "tabHomeSelectedIcon")?.tint(with: Color.red.accent3)
    }
}
OrkhanAlikhanov commented 6 years ago

Your convenience init is not used to initialize the NavigationController, so preparetabBarItem is not called during init. Override the initializer you are using, which is init(rootViewController:) in your case.

Also prepare() is an alias for viewDidLoad(), use one at a time, and always call super.prepare() or super.viewDidLoad() when override

class ContestNavigationViewController: NavigationController {

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
        preparetabBarItem()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func prepare() {
        super.prepare()
        guard let v = navigationBar as? NavigationBar else {
            return
        }

        v.depthPreset = .none
        v.dividerColor = Color.grey.lighten1

        navigationBar.tintColor = Color.red.accent4
        preparetabBarItem()
    }
}

extension ContestNavigationViewController {
    fileprivate func preparetabBarItem() {
        tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -4)
        tabBarItem.image = UIImage(named: "tabHomeIcon")?.tint(with: Color.grey.base)
        tabBarItem.title = "HOME"
        tabBarItem.selectedImage = UIImage(named: "tabHomeSelectedIcon")?.tint(with: Color.red.accent3)
    }
}
manas-somoy commented 6 years ago

This gives an error - ContestNavigationViewController.swift: 12: 7: Fatal error: Use of unimplemented initializer 'init(nibName:bundle:)' for class 'Uthabo.ContestNavigationViewController'

daniel-jonathan commented 6 years ago

@CHONUMAN If you are using storyboards, I believe you need to implement that initializer.

OrkhanAlikhanov commented 6 years ago

@CHONUMAN Simply implement it in your ContestNavigationViewController:

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

This is well-known:

Unlike subclasses in Objective-C, Swift subclasses do not inherit their superclass initializers by default.

SDGMazeGeek commented 6 years ago

I'll check it tonight. Thanks.

daniel-jonathan commented 6 years ago

@SDGMazeGeek Thank you for sharing your issue. If you have another, or still need help with this one, please reopen the issue.