Проблемы компоновки после замены UILabel на UITextView в UITableViewCell - PullRequest
0 голосов
/ 27 марта 2020

У меня есть базовые функции чата c как часть приложения, которое я создаю. По сути, это представление UITable, где UITableViewCell содержит только UILabel (текст сообщения чата) и UIView (выступающий в качестве речевого пузыря, окружающий текст. Вот код:

class ChatMessageViewCellController: UITableViewCell {

    var ChatMessageText = UILabel()
    var ChatBubble = UIView()
    var leadingConstraint: NSLayoutConstraint!
    var trailingConstraint: NSLayoutConstraint!
    var isIncoming: Bool! {
        didSet {
            if self.isIncoming {
                self.ChatBubble.backgroundColor = UIColor(named: "customGrey")
                self.leadingConstraint.isActive = true
                self.trailingConstraint.isActive = false
            } else {
                self.ChatBubble.backgroundColor = UIColor(named: "customGreen")
                self.leadingConstraint.isActive = false
                self.trailingConstraint.isActive = true
            }
        }
    }



    override func awakeFromNib() {
        super.awakeFromNib()

        addSubview(ChatBubble)
        addSubview(ChatMessageText)

        self.ChatBubble.translatesAutoresizingMaskIntoConstraints = false
        self.ChatMessageText.translatesAutoresizingMaskIntoConstraints = false

        self.ChatBubble.backgroundColor = UIColor(named: "customGreen")
        self.ChatBubble.layer.cornerRadius = 10
        self.ChatMessageText.numberOfLines = 0
        self.ChatMessageText.textColor = .white
        self.ChatMessageText.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.light)

        let constraints = [
            self.ChatMessageText.topAnchor.constraint(equalTo: topAnchor, constant: 16),
            self.ChatMessageText.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -32),
            self.ChatMessageText.widthAnchor.constraint(lessThanOrEqualToConstant: 220),
            self.ChatBubble.topAnchor.constraint(equalTo: ChatMessageText.topAnchor, constant: -16),
            self.ChatBubble.trailingAnchor.constraint(equalTo: ChatMessageText.trailingAnchor, constant: 16),
            self.ChatBubble.bottomAnchor.constraint(equalTo: ChatMessageText.bottomAnchor, constant: 16),
            self.ChatBubble.leadingAnchor.constraint(equalTo: ChatMessageText.leadingAnchor, constant: -16),
        ]

        NSLayoutConstraint.activate(constraints)

        self.leadingConstraint = self.ChatMessageText.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 32)
        self.trailingConstraint = self.ChatMessageText.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -32)
    }

My проблема заключается в следующем: Я не загружаю UILabel стандартными строками, а использую NSAttributedStrings, так как я хотел бы, чтобы некоторые ссылки были кликабельными, а части текста выбирались пользователем. велел использовать UITextView вместо UILabel, поэтому я сделал следующие 2 изменения:

  1. Изменил var ChatMessageText = UILabel() на var ChatMessageText = UITextView()
  2. Удалил self.ChatMessageText.numberOfLines = 0 как UITextView не имеет numberOfLines члена

XCode не жалуется, и приложение компилируется и запускается, но полностью мешает моему макету, и я просто не могу понять, почему. Все ограничения из UILabel также должен работать для UITextView - по крайней мере, я так думал. Но вот как выглядит экран.

enter image description here

Что я делаю не так? Нужно ли добавлять / изменить ограничения?

1 Ответ

0 голосов
/ 30 марта 2020

По умолчанию для UITextView включена прокрутка.

Хотя это кажется очевидным, это позволяет пользователю вводить больше строк текста, чем уместится в рамке, и пользователь может прокручивать текст вверх и вниз.

Для того, чтобы это случается, UIKit должен знать рамку текстового представления. Если кадр не задан, UIKit не может узнать, сколько строк нужно отобразить или насколько широко должен быть вид. Таким образом, если мы не предоставим текстовому представлению полный набор ограничений, автоматическое размещение даст ему размер .zero. Даже если задано ограничение ширины (или максимальной ширины), автоматическое размещение все равно не знает, сколько прокручиваемых строк текста мы хотим отобразить.

Настройка .isScrollEnabled = false в текстовом представлении меняет все это.

Теперь, если мы ограничим только положение и width текстового представления, UIKit вычислит высоту на основе размера содержимого .text свойство.

Это легко показать. Мы создадим два текстовых представления, дадим им каждое ограничение верхней, верхней и максимальной ширины (lessThanOrEqualTo) и один и тот же текст ... но установим .isScrollEnabled = false для одного из них:

class TextViewTestViewController: UIViewController {

    let nonScrollingTextView = UITextView()
    let scrollingTextView = UITextView()

    override func viewDidLoad() {

        super.viewDidLoad()

        let s = "This is a test string to demonstrate UITextView size behavior."

        [nonScrollingTextView, scrollingTextView].forEach {
            tv in
            tv.translatesAutoresizingMaskIntoConstraints = false
            tv.font = UIFont.systemFont(ofSize: 17.0)
            tv.text = s
            view.addSubview(tv)
        }

        let g = view.safeAreaLayoutGuide

        NSLayoutConstraint.activate([

            nonScrollingTextView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            nonScrollingTextView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
            nonScrollingTextView.widthAnchor.constraint(lessThanOrEqualToConstant: 300.0),

            scrollingTextView.topAnchor.constraint(equalTo: nonScrollingTextView.bottomAnchor, constant: 40.0),
            scrollingTextView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
            scrollingTextView.widthAnchor.constraint(lessThanOrEqualToConstant: 300.0),

        ])

        // disable scrolling on the "top" text view
        nonScrollingTextView.isScrollEnabled = false

        // top text view is cyan
        nonScrollingTextView.backgroundColor = .cyan

        // bottom text view is green (although we won't see it)
        scrollingTextView.backgroundColor = .green

    }

}

Результат :

enter image description here

Мы добавили два текстовых представления, но отключили прокрутку только на «верхнем» (голубой фон). Мы даже не видим второй (зеленый фон), потому что автоматическое расположение дает ему высоту Ноль.

Стоит отметить ... если в текстовом представлении отключена прокрутка и если редактирование включено, оно будет автоматически увеличиваться / уменьшаться по мере добавления / удаления текста пользователем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...