Автоматическое изменение размера UIView на основе содержимого UILabel с помощью Auto Layout - PullRequest
0 голосов
/ 10 января 2019

У меня есть требование показа баннера, чтобы показать сообщение,

Теперь содержимое сообщения может меняться, и размер представления также должен изменяться в зависимости от содержимого UILabel s.

UILabel установлен на Word Wrap, а numberOfLines установлен на 0

Дизайн в xib есть, Auto layoutAuto Layout 2

И соответствующий файл класса,

import UIKit

class ORABannerView: UIView {

    @IBOutlet weak var bannerText: UILabel!

    static func instantiate(message: String) -> ORABannerView {
        let view: ORABannerView = initFromNib() ?? ORABannerView()
        view.bannerText.text = message
        return view
    }

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

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

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    }
}

initFromNib реализован как расширение UIView,

extension UIView {
    class func initFromNib<T: UIView>() -> T? {
        guard let view = Bundle.main.loadNibNamed(String(describing: self), owner: nil, options: nil)?[0] as? T else {
            return nil
        }
        return view
    }
}

Пробовал с layoutIfNeeded() на виде, но у меня не работает.

Будем благодарны за любые предложения.

Ответы [ 4 ]

0 голосов
/ 11 января 2019

Автопоставка новых пользователей, всегда забывал о двух полезных ограничениях:

func setContentCompressionResistancePriority(UILayoutPriority, for: NSLayoutConstraint.Axis)
func setContentHuggingPriority(UILayoutPriority, for: NSLayoutConstraint.Axis)

Он также существует в IB: enter image description here

Попробуйте поиграть с параметром приоритета

0 голосов
/ 10 января 2019

Я ожидаю, что класс будет выглядеть

class ORABannerView: UIView {

    @IBOutlet weak var bannerText: UILabel!

    static func instantiate(message: String) -> ORABannerView {
        let view: ORABannerView = initFromNib()
        view.bannerText.text = message
        return view
    }

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

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

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    }
}

let v = ORABannerView.instantiate(message: "djhhejjhsdjhdjhjhdshdsjhdshjdhjdhjdhjddhjhjdshjdhdjshjshjdshjdshjdshjdshjdsjhdshjds")

self.view.addSubview(v)

v.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([

    v.topAnchor.constraint(equalTo: self.view.topAnchor,constant:50),

    v.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant:0),

    v.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant:0)

])

enter image description here

0 голосов
/ 11 января 2019

Вы можете попробовать следующий код,

Создайте метод sizeHeaderToFit, который возвращает высоту UIView в зависимости от высоты его содержимого.

private func sizeHeaderToFit(headerView: UIView?) -> CGFloat {
       guard let headerView = headerView else {
           return 0.0
       }

       headerView.setNeedsLayout()
       headerView.layoutIfNeeded()

       let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height

       return height
   }

Затем вы можете вызвать вышеуказанный метод из соответствующего кода,

sizeHeaderToFit(headerView: yourView)

В ORABannerView классе, добавить переопределение layoutSubviews,

override func layoutSubviews() {
       super.layoutSubviews()
       bannerText.preferredMaxLayoutWidth = bannerText.bounds.width
   }

А в файле xib сохраните ограничения для superview вместо safe area для оптимизации кода. [Необязательно]

Надеюсь, это поможет.

0 голосов
/ 10 января 2019
  1. Снять конечные ИЛИ ведущие ограничения
  2. установить размер для программного соответствия свойства
...