Jakub
Jakub

Reputation: 13860

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?

Upvotes: 10

Views: 12427

Answers (3)

Divyesh Makwana
Divyesh Makwana

Reputation: 97

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)
])

Upvotes: 1

Krunal
Krunal

Reputation: 79776

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.

Upvotes: 9

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

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)

Upvotes: 3

Related Questions