简体   繁体   中英

Multiline UILabel on navigation bar title view

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 UINavigationBar ' titleView 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()
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM