iosswiftuinavigationcontrolleruinavigationbartitleview

how to set width of navigationTitleView and Truncate label by swift3


I have a problem about navigation titleView.
The titleView cover my right barbuttonItem and out of screen.
I need titleView just in center region and have right region for barbuttonItem.
I want to know how to set width about my title, because I can't set width successfully.
And I also want to truncating middle the label.
What's wrong with me?
Thanks.

Here is Image about my question.
Here is Image about my question.

self.navigationItem.titleView = setTitle(title: name, subtitle: "")


func setTitle(title:String, subtitle:String) -> UIView {
    let titleLabel = UILabel(frame: CGRect(x:0, y:5, width:0, height:0))

    titleLabel.backgroundColor = UIColor.clear
    titleLabel.textColor = UIColor.white
    titleLabel.font = defaultTitleFont
    titleLabel.text = title
    titleLabel.sizeToFit()

    let subtitleLabel = UILabel(frame: CGRect(x:5, y:18, width:0, height:0))
    subtitleLabel.backgroundColor = UIColor.clear
    subtitleLabel.textColor = UIColor.red
    subtitleLabel.font = UIFont.systemFont(ofSize: 20)
    subtitleLabel.text = subtitle
    subtitleLabel.sizeToFit()

    let titleView = UIView(frame: CGRect(x:0, y:0, width:max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), height:35))
    titleView.addSubview(titleLabel)
    //titleView.addSubview(subtitleLabel)

    let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width

    if widthDiff > 0 {
        var frame = titleLabel.frame
        frame.origin.x = widthDiff / 2
        titleLabel.frame = frame.integral
    } else {
        var frame = subtitleLabel.frame
        frame.origin.x = abs(widthDiff) / 2
        subtitleLabel.frame = frame.integral
    }

    return titleView
}

Solution

  • You have to calculate the title view size/frame beforehand. One possible way to do this to take consideration of screen width and number of bar button items presented in the navigation bar.

    Take a look at the following code (Simplified for showing only title, no subtitle):

    func getTitleView (title:String, numOfButtons: Int = 0) -> UIView {
        let barButtonSize = 70
        let offset: CGFloat = CGFloat(numOfButtons * barButtonSize)
        let frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width - offset, height: 35)
        let titleView = UIView(frame:frame)
    
        let titleLabel = UILabel(frame: titleView.bounds)
    
        titleLabel.backgroundColor = UIColor.clear
        titleLabel.textColor = UIColor.red
        titleLabel.font = UIFont.systemFont(ofSize: 14)
        titleLabel.text = title
        titleLabel.numberOfLines = 1
        titleLabel.textAlignment = .center
        titleLabel.lineBreakMode = .byTruncatingMiddle
        titleView.addSubview(titleLabel)
        return titleView
    }
    

    And from viewDidLoad:

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: nil)
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: nil)
    
        self.navigationItem.titleView = getTitleView(title: "Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow WowWow Wow Wow Wow Wow Wow Wow WowWow WowWowWowWowWowWowWowWow Wow Wow Wow Wow Wow Wow Wow!!", numOfButtons: 2)
    }
    

    And output: enter image description here