Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITabBar with safe area inside programmatically created UIViewController

Before you mark it as duplicate please note, that I did read this and this seems to not apply to UITabBar

Both UIViewController and UITabBar are created programmatically. Constraints are set like:

public override func viewDidLoad() {
    super.viewDidLoad()
    self.view.bringSubview(toFront: self.tabBar)
}

And self.tabBar:

lazy var tabBar: UITabBar = {
    let tab = UITabBar()
    self.view.addSubview(tab)
    tab.translatesAutoresizingMaskIntoConstraints = false
    tab.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
    tab.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
    tab.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true //This line will change in second part of this post.
    return tab
}()

And this show UITabBar like this:

enter image description here

And it's too small cause it's not taking safe areas into consideration. So I did change line:

tab.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

to:

tab.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor).isActive = true

And it's then shown like this:

enter image description here

So it's also not shown as expected. The goal here is sth like this:

enter image description here

How to make constraints to show UITabBar like this?

like image 496
Jakub Avatar asked May 17 '18 12:05

Jakub


3 Answers

Here I did it:

let tabBar = UITabBar()

override func viewDidLoad() {
    super.viewDidLoad()
    addTabbar()
}
override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    addHeightConstraintToTabbar()
}

func addTabbar() -> Void {
    self.view.addSubview(tabBar)
    tabBar.translatesAutoresizingMaskIntoConstraints = false
    tabBar.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
    tabBar.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
    tabBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    let item1 = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.bookmarks, tag: 1)
    let item2 = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 2)

    tabBar.items = [item1, item2]
    self.view.bringSubview(toFront: tabBar)
}

func addHeightConstraintToTabbar() -> Void {
    let heightConstant:CGFloat = self.view.safeAreaInsets.bottom + 49.0
    tabBar.heightAnchor.constraint(equalToConstant: heightConstant).isActive = true
}

Result:

enter image description here


May not know, is it correct to do in this way. You need to make it better.

like image 59
Krunal Avatar answered Oct 21 '22 18:10

Krunal


When you add UItabbar to UIViewController and use safeAreaLayoutGuide or layoutMarginsGuide it will be added to save area of that view controller which have SafeAreaInsets with space at bottom you can change, but if you add to View of UIViewController it will be stick to edge without any space , with default hight 49

to increase that hight add heightAnchor constraint

  lazy var tabBar: UITabBar = {
        let tab = UITabBar()
        self.view.addSubview(tab)
        tab.translatesAutoresizingMaskIntoConstraints = false
        tab.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
        tab.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
        tab.heightAnchor.constraint(equalToConstant: 80).isActive = true
        tab.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true //This line will change in second part of this post.
        return tab
    }()

to use safe area guide you can add negative value to Bottom of additionalSafeAreaInsets of ViewController

self.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, -39, 0)
like image 42
Abdelahad Darwish Avatar answered Oct 21 '22 16:10

Abdelahad Darwish


The bottom anchor needs to be connected to view's safeAreaLayoutGuide.

tabbar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    tabbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    tabbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    tabbar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
like image 26
Divyesh Makwana Avatar answered Oct 21 '22 18:10

Divyesh Makwana