Reputation: 6732
The code:
let size = CGSize(width: tabBar.frame.width / CGFloat(TabBarItem.allValues.count),
height: tabBar.frame.height)
let image = UIImage.image(color: Color.action, size: size)
UITabBar.appearance().selectionIndicatorImage = image
On usual devices looks like this:
On iPhone X like this:
What can be the reason why iPhone X tab bar item background is misaligned?
UPDATE 1:
After changing code to be like below it looks better but it is still workaround as image not fully occupies tab bar item space:
var image: UIImage
if DeviceInfo.is5p8Inch {
image = UIImage.image(color: Color.action, size: CGSize(width: 4, height: 4))
image = image.resizableImage(withCapInsets: UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2), resizingMode: .tile)
} else {
let size = CGSize(width: tabBar.frame.width / CGFloat(TabBarItem.allValues.count),
height: tabBar.frame.height)
image = UIImage.image(color: Color.action, size: size)
}
UPDATE 2:
Code above called from viewDidLoad
(also tries from viewWillAppear
). Subclass of UITabBarController
written 100% from code (no Storyboards/Xibs used).
UPDATE 3:
We also have a custom button added as subview to UITabBar which positioned correctly. Only selectionIndicatorImage
is misaligned...
UPDATE 4:
Running original code above in viewDidAppear
instead of in viewDidLoad
or viewWillAppear
produces following result:
Upvotes: 6
Views: 1485
Reputation: 432
You just need to call it after delay because it didn't get correct height of tabBar in your case and set it in self.tabBar, bellow code works for me i did it in viewDidload
Async.main {
let size = CGSize(width: tabBar.frame.width / CGFloat(TabBarItem.allValues.count),
height: tabBar.frame.height)
let image = UIImage.image(color: Color.action, size: size)
UITabBar.appearance().selectionIndicatorImage = image
self.tabBar.selectionIndicatorImage = image // this will change color and height of current tabBar
}
Upvotes: 1
Reputation: 896
Try this one
Make extension of image which generate color image.
extension UIImage {
class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
And set that image to tabbarcontroller and set 48 height of tabbar
var tabFrame = self.tabBarController.tabBar.frame
//self.TabBar is IBOutlet of your TabBar
tabFrame.size.height = 48
tabFrame.origin.y = self.window!.frame.size.height - 48
self.tabBarController.tabBar.frame = tabFrame
self.tabBarController.tabBar.autoresizesSubviews = false
self.tabBarController.tabBar.clipsToBounds = true
self.tabBarController.delegate = self
tabNavigation = UINavigationController(rootViewController: self.tabBarController)
tabNavigation.isNavigationBarHidden = true
let numberOfItems = CGFloat((tabBarController.tabBar.items!.count))
let tabBarItemSize = CGSize(width: (tabBarController.tabBar.frame.width) / numberOfItems,
height: (tabBarController.tabBar.frame.height))
tabBarController.tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor(red: 90/255.0, green: 43/255.0, blue:123/255.0, alpha: 1.0), size: tabBarItemSize).resizableImage(withCapInsets: UIEdgeInsets.zero)
tabBarController.tabBar.frame.size.width = self.window!.frame.width + 4
tabBarController.tabBar.frame.origin.x = -2
Upvotes: 0
Reputation: 528
try, this worked for me. not sure if it will work for all.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tabbar.invalidateIntrinsicContentSize()
}
Upvotes: 0