Multiline UILabel on navigation bar title view

Published

I have a custom UIView which has 2 UILabel (same width) and one UIImageView (known width of 44pt). Width sizes are given as an example, they can change but It is exact that UILabels should has same width and UIImage has a 44 point width. I want to add this view to UINavigationBartitleView BUT ImageView should be in the center of navigation bar.

(60 width) UILabel---UIImageView (44 width) ---UILabel (60 width)

I want is that UILabels to have maximum two line and adJustFontSizeToFitWidth true. I’m giving specific width and height to title view but labels get two line but their font size doesn’t change even they don’t fit the view.

How I add titleView:

 navigationItem.titleView = myTitleView
    let widthOfItem: CGFloat = 30.0
    let pading: CGFloat = 40
    let aWidth: CGFloat = (self.navigationController?.navigationBar.frame.width)! - CGFloat(1) * widthOfItem * 2.0 - pading

    myTitleView { (make) in
        make.width.equalTo(aWidth)
        make.height.equalTo(44)
    }

MyCustomView:

override func layoutSubviews() {
    super.layoutSubviews()
    let preferredWidth = (bounds.width / 2) - 56
    firstLabel.preferredMaxLayoutWidth = preferredWidth
    secondLabel.preferredMaxLayoutWidth = preferredWidth
}

private func setupViews() {

    addSubview(firstLabel)
    addSubview(myImageView)
    addSubview(secondLabel)

    firstLabel.font = .myFont(.bold, size: 36)
    firstLabel.adjustsFontSizeToFitWidth = true
    firstLabel.minimumScaleFactor = 0.5
    firstLabel.textColor = .textPrimary
    firstLabel.numberOfLines = 2
    firstLabel.lineBreakMode = .byWordWrapping
    firstLabel.textAlignment = .right

    myImageView.contentMode = .scaleAspectFit
    myImageView.clipsToBounds = true
    myImageView.layer.minificationFilter = .trilinear
    myImageView.layer.cornerRadius = currencyImageSize.height / 2

    secondLabel.font = . myFont(.bold, size: 36)
    secondLabel.translatesAutoresizingMaskIntoConstraints = false
    secondLabel.textColor = .textPrimary
    secondLabel.numberOfLines = 2
    secondLabel.adjustsFontSizeToFitWidth = true
    secondLabel.baselineAdjustment = .none
    secondLabel.minimumScaleFactor = 0.5
    secondLabel.lineBreakMode = .byWordWrapping
    secondLabel.textAlignment = .left

    firstLabel.snp.makeConstraints { (make) in
        make.leading.equalToSuperview()
        make.top.bottom.equalToSuperview()
        make.trailing.equalTo(myImageView.snp.leading).offset(-12)
    }

    myImageView.snp.makeConstraints { (make) in
        make.height.equalToSuperview()
        make.width.equalTo(myImageView.snp.height)
        make.centerX.equalToSuperview()
    }
   secondLabel.snp.makeConstraints { (make) in
        make.top.bottom.equalToSuperview()
        make.leading.equalTo(myImageView.snp.trailing).offset(12)
        make.trailing.equalToSuperview()
    }
}

Source: Ios

Published
Categorised as ios, swift, uilabel, uiview

Answers

Maybe this code will work?


class CustomNavClass: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup_view()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup_view()
    }

    private func setup_view() {
        backgroundColor = .lightGray

        let image = UIImageView(image: .init())
        addSubview(image)

        image.translatesAutoresizingMaskIntoConstraints = false
        image.backgroundColor = .green

        NSLayoutConstraint.activate([
            image.centerXAnchor.constraint(equalTo: centerXAnchor),
            image.widthAnchor.constraint(equalToConstant: 44),
            image.heightAnchor.constraint(equalToConstant: 44),

            image.topAnchor.constraint(equalTo: topAnchor, constant: 3),
            image.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -3)
        ])

        let leftLabel = UILabel()
        leftLabel.text = "Label label left long label will go here, naturally"
        leftLabel.numberOfLines = 2
        leftLabel.adjustsFontSizeToFitWidth = true
        leftLabel.backgroundColor = .red

        addSubview(leftLabel)

        leftLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            leftLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            leftLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
            leftLabel.trailingAnchor.constraint(equalTo: image.leadingAnchor, constant: -10)
        ])

        let rightLabel = UILabel()
        rightLabel.text = "Label label right long label will go here, naturally"
        rightLabel.numberOfLines = 2
        rightLabel.adjustsFontSizeToFitWidth = true
        rightLabel.backgroundColor = .blue

        addSubview(rightLabel)

        rightLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            rightLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
            rightLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
            rightLabel.leadingAnchor.constraint(equalTo: image.trailingAnchor, constant: 10)
        ])
    }
}

The code does not use a UIStackView as its limited to its function (specifically, only one UIView can be stretched out on .fill distribution property.

This instead creates layout constraints:

  1. UIImageView that is pegged at the center(with a 3 top and bottom constraint, optional, you can use centerY constraint or the like).
  2. Leading UILabel is pegged to leading edge and trailing edge with UIImageView‘s leading edge.
  3. Trailing UILabel is pegged to trailing edge and leading edge with UIImageView‘s trailing edge.


Letitia Towne

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq