Reputation: 16416
I am trying to add custom view (Label) as title view of navigation item.
but it is not appearing in centre
func setupNavigationMultilineTitle(title:String) {
let autoscrollLabel = EFAutoScrollLabel()
autoscrollLabel.text = title
autoscrollLabel.textAlignment = .center
autoscrollLabel.backgroundColor = .red
autoscrollLabel.font = AppTheme.Fonts.font(type: .Medium, size: 15)
autoscrollLabel.textColor = AppTheme.Colors.ColorsOfApp.header_color.color
autoscrollLabel.frame = CGRect(x: 0, y: 0, width:((self.navigationController?.navigationBar.frame.size.width ?? 0) - (self.navigationItem.leftBarButtonItem?.customView?.frame.width ?? 0) * 2) , height: 40)
self.navigationItem.titleView = autoscrollLabel
}
I have tried to use deduct width of custom view to show it in center but unfortunately it is not working.
I have also tried to get self.navigationItem.leftBarButtonItem.width
but it returns 0. I confirmed that there is leftBarbutton item with po self.navigationItem.leftBarButtonItem
EDIT
This solves issue
autoscrollLabel.frame = CGRect(x: self.view.center.x - 125, y: 0, width: 250 , height: 40)
But I need dynamic solution
Any help would be appreciated
Upvotes: 1
Views: 3008
Reputation: 43
Add my version code based on @dahiya_boy answers. In my case, I have a custom button that has a more 30-width size. So, rather than multiply it by 30, I find a max from left and right items to find the max. Below is the code:
func setCenterTitle(_ title: String) {
let navWidth = (navigationController?.navigationBar.frame.width).orZero
let leftItemsWidth = leftBarButtonItems.orEmptyArray.reduce(0) {
$0 + ($1.customView?.frame.width).orZero
}
let rightItemsWidth = rightBarButtonItems.orEmptyArray.reduce(0) {
$0 + ($1.customView?.frame.width).orZero
}
let maxItemsWidth = max(leftItemsWidth, rightItemsWidth)
let padding: CGFloat = 40
let labelWidth = navWidth - (maxItemsWidth * 2) - padding
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: labelWidth, height: 40))
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.font = UIFont.boldSystemFont(ofSize: 16)
self.titleView = titleLabel
}
Upvotes: 0
Reputation: 9503
I debugged your scenario, hope it helps you and other developers,
When we assign tittleView width by calculating the space left after subtracting space of items, margins, padding etc then iOS calculate titleView X from the right side i.e. titleview.x = rightItem.x - width
and we are expecting it like titleview.x = navbar.width/2 - width/2
.
Please look below sample test cases.
Calculate width
let maxItemOnEitherSide = max(arrLeftItems.count, arrRightItems.count)
let widthOfItem : CGFloat = 30.0
let pading : CGFloat = 40
let aWidth : CGFloat = (self.navigationController?.navigationBar.frame.width)! - CGFloat(maxItemOnEitherSide) * widthOfItem * 2.0 - pading
let lblNavTitle = UILabel(frame: CGRect(x: 0, y: 0,
width: aWidth,
height: 40))
Case 1 : arrLeftItems.count = 1 and arrRightItems.count = 0.
Output :
Case 2 : arrLeftItems.count = 0 and arrRightItems.count = 1.
Hope above cases clear you out what we are expecting and what we are getting and the calculation that I wrote in first para i.e. titleview.x = rightItem.x - width
.
Conclusion :
If rightBarItems have more items than leftBarItems then titleview will be in center, so you wont need to do anything but if leftBarItems have more items than rightBarItems then add blank items in right side to make it balance. It is weird for developers but seems like its the only solution.
Check the final output.
Upvotes: 4
Reputation: 31
If your navigation Item is part of a UINavigationController you could try
self.navigationController?.navigationBar.topItem?.leftBarButtonItem?.width ?? 0.0
Upvotes: 0