Этот вопрос касается поддержки настраиваемого текстового представления переменной высоты с использованием ограничений и представления intrinsicContentSize для autolayout.Прежде, чем вы нажмете эту кнопку «дубликата», выслушайте меня.
У меня есть собственное представление текста (с нуля, наследуется от NSView).Он поддерживает многие обычные функции NSTextView, наиболее релевантными здесь являются несколько строк и расположение их содержимого на основе доступной ширины.Приложение, для которого оно создано, загружает несколько этих текстовых представлений в каждую строку табличного представления.Проблема в том, что высота не установлена должным образом в соответствии с его intrinsicContentSize.
Я создал пример проекта , который упрощает проблему.Он использует «псевдо» текстовое представление с фиксированным числом и размером символов, используемое для определения требуемой ширины / высоты.В этом примере есть табличное представление одного столбца, представление ячейки которого имеет только одно подпредставление, PseudoTextView.Текстовое представление прикреплено к краям его представления ячейки с небольшим дополнением.Как я могу заставить систему распознавать, что текстовое представление должно подчиняться ограничениям, которые определяют ширину, в то же время позволяя текстовому виду увеличиваться по высоте, плотно обтянутому представлением ячейки?Вот код текстового представления:
class PseudoTextView: NSView {
@IBInspectable var characterCount: Int = 0
@IBInspectable var characterWidth: CGFloat = 5
@IBInspectable var characterHeight: CGFloat = 8
@IBInspectable var background: NSColor = .blue {
didSet {
layer?.backgroundColor = background.cgColor
}
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
wantsLayer = true
layer?.backgroundColor = background.cgColor
}
override var intrinsicContentSize: NSSize {
let requiredWidth = characterWidth * CGFloat(characterCount)
let lineCount = (requiredWidth / frame.width).rounded(.up)
let usedHeight = lineCount * characterHeight
let charactersPerLine = (frame.width / characterWidth).rounded(.down)
let usedWidth = charactersPerLine * characterWidth
return NSSize(width: usedWidth, height: usedHeight)
}
Эта версия возвращает соответствующий размер в зависимости от кадра представления.Это, очевидно, не работает, потому что к нему обращаются во время фазы макета updateConstraints, когда кадр не был установлен.Я также попытался использовать NSView.noIntrinsicMetric для ширины, но это приведет текстовое представление к нулевой ширине, и высота никогда не восстанавливается.Я сделал огромное количество других попыток, но я не буду утомлять вас ими.
NSTextField делает что-то другое (при условии, что 'Editable' выключен, 'Wrap' включен).Это intrinsicContentSize сообщает всю ширину текста в одной строке (даже если она намного длиннее доступной ширины), но его размер каким-то образом изменяется до правильной ширины.После изменения размера intrinsicContentWidth по-прежнему сообщает полную ширину одной строки, но высота корректируется для учета нескольких строк.Где-то есть магия, которую я не смог разгадать.
Я прочитал каждую строку соответствующей документации.Если в теме есть пост в блоге, я, наверное, его прочитал.Если есть вопрос о SO по этой теме, я, вероятно, прочитал его.Если вы написали книгу на эту тему, я, вероятно, купил ее.Все эти источники дразнят мою проблему, но ни один из них не отвечает на вопрос, как справиться с этой конкретной ситуацией.Отчаянно.
Обновление:
После прочтения старого сообщения в блоге Джонатона Маха (http://devetc.org/code/2014/07/07/auto-layout-and-views-that-wrap.html) я создал пример, использующий его подход. Вот другой проект это имитирует его технику и работает правильно. Это верхняя часть приложения. Это фиксированный вид контейнера, который настраивается с помощью ползунка. Пэчворк - это псевдосимволы пользовательского вида, фон которого - розовый.
Тем не менее, при вставке в представление таблицы с автоматическими размерами пользовательское представление правильно соответствует ширине его ячейки, но ячейка не регулируется в соответствии с внутренней высотойЕсли вы измените нижнее ограничение пользовательского представления на необязательное (скажем, с отношением> =), пользовательское представление сжимается до правильной высоты, но представление ячейки остается фиксированным. Как убедить представление ячейки уменьшить его высоту доуважать intrinsicContentSize.height его подпредставления?