Reputation: 1421
I increased my tab bar height via changing the frame of the tabBar
in my custom UITabBarController
class in viewDidLayoutSubviews()
.
However, the tab bar buttons do not remain vertically centered.
I tried to access the UITabBarButton
views and set the frame manually, but it does not stay (has no effect). Not sure why the new frame is being reset/ignored. I also tried doing it in viewDidAppear()
to no avail. Running out of ideas. Using Reveal app to edit it has no issues (not sure what they are doing to get it to stick).
Is there any way I can edit the frame of the button?
Upvotes: 0
Views: 2568
Reputation: 1421
I figured it out. It was a silly mistake of mine - forgot to remove a test set frame code. Either way, here is what I did and it has to be done in viewDidAppear()
because that is where the button frames are properly updated and only then can we act on it (if anyone knows of a better way, please leave a comment!).
First of all I had to increase the height of the tab bar:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Increase by 16 pt.
let newTabBarHeight = tabBar.frame.size.height + 16
var newFrame = tabBar.frame
newFrame.size.height = newTabBarHeight
newFrame.origin.y = view.frame.size.height - newTabBarHeight
tabBar.frame = newFrame
}
Then shift the buttons y-position:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let buttons = tabBar.subviews.filter { String(describing: type(of: $0)) == "UITabBarButton" }
buttons.forEach {
// Getting the button's superview height (probably can just take the tab bar `tabBar.frame.size.height` and remove the `if`).
if let superviewHeight = $0.superview?.frame.height {
// Accounted for the safe area insets for iPhone X and above.
$0.center = CGPoint(x: $0.frame.midX, y: superviewHeight * 0.5 - ((appDelegate.window?.safeAreaInsets.bottom ?? 0) * 0.5))
}
}
}
The above should hopefully work if the device rotated or for an iPad, but I did not test it out.
Here is alternate version using autolayout constraints for reference (since this is not so flexible if the bar changes width):
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let buttons = tabBar.subviews.filter { String(describing: type(of: $0)) == "UITabBarButton" }
buttons.forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
$0.centerYAnchor.constraint(equalTo: superview.centerYAnchor,
constant: ((appDelegate.window?.safeAreaInsets.bottom ?? 0) * 0.5) : 0),
$0.heightAnchor.constraint(equalToConstant: $0.frame.height),
$0.widthAnchor.constraint(equalToConstant: $0.frame.width),
$0.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: $0.frame.minX)
])
}
Unfortunately both will visibly show a jump in the buttons (moving from top to center) since it happens in viewDidAppear()
, even for the autolayout constraints version. The alternative solution I believe would be to create our own tab bar though I have not done that before and am not sure what other implications that would have.
Hope this helps someone out as well.
Upvotes: 1