invalidationContext (forPreferredLayoutAttributes: withOriginalAttributes :) не вызывается для пользовательского подкласса NSCollectionViewLayout - PullRequest
0 голосов
/ 23 сентября 2018

Ссылка на соответствующий пример проекта

Описание

Я пытаюсь создать собственный подкласс NSCollectionViewLayout, который использует Auto Layout для определения своих элементов 'размеры.Этот макет размещает элементы сверху вниз, где все элементы имеют одинаковую ширину, но высота каждого элемента определяется его содержимым.Думайте об этом как о макете UITableView для macOS.

Предположение

Первоначальные атрибуты макета вычисляются в методе prepare() макета и передаются в представление коллекции через layoutAttributesForElements(in:).Эти атрибуты используются представлением коллекции, чтобы определить, какие элементы необходимо отобразить.Эти элементы предоставляются делегатом представления коллекции, и для настройки свойств его представления вызывается метод apply(_:) каждого элемента.

Представление коллекции затем вызывает метод preferredLayoutAttributesFitting(_:) элемента для вычисления его содержимого.подходящий размер.Затем возвращенные атрибуты будут переданы в метод shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) макета представления коллекции, где макет определяет, нужно ли ему вносить изменения в ответ на новые атрибуты, и возвращает это логическое решение в представление коллекции.

Если макет решит, что он должен быть признан недействительным, представление коллекции затем вызовет invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:), чтобы получить из макета конкретную информацию о том, как он должен обновляться.Когда представление коллекции затем вызывает invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:), макет может применить эти изменения.

Этот процесс повторяется до тех пор, пока shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) не вернет false для каждого элемента макета, что заставит представление коллекции отображать элементы наэкран.

Помещение

Подкласс ListLayout из NSCollectionViewLayout способен создавать начальный набор атрибутов макета для каждого NSCollectionViewItem с "предполагаемой" начальной высотой 10 точки.Мы ожидаем использовать Auto Layout для определения фактической высоты каждого элемента, поэтому это начальное значение не должно иметь значения.

В этом случае макет может предоставить правильный набор этих начальных атрибутов через layoutAttributesForElements(in:).

Подкласс TextFieldItem в NSCollectionViewItem содержит один экземпляр NSTextField, для которого установлены оба свойства view и textField.Для этого вида свойство translatesAutoresizingMaskIntoConstraints имеет значение false и имеет требуемый приоритет сопротивления сжатию вертикального содержимого.Метод элемента apply(_:) переопределяется, чтобы задать для preferredMaxLayoutWidth текстового поля ширину, заданную данными атрибутами.Метод элемента preferredLayoutAttributesFitting(_:) переопределяется, чтобы установить высоту предпочтительного атрибута равной свойству intrinsicContentSize текстового поля.

Представлению коллекции предоставляются экземпляры TextFieldItem, заполненные несколькими строками текста.

Ожидается, что у каждого TextFieldItem будет свой метод preferredLayoutAttributesFitting(_:), вызываемый после его метода apply(_:), за которым следует вызов обоих методов макета shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) и invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:).

Однако, ни preferredLayoutAttributesFitting(_:), ни shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:), ни invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:) никогда не вызываются при запуске игровой площадки.В результате высота каждого предмета остается на этой начальной «оценочной» высоте.

Each text field should display three lines of text, but only the top of the first line is visible.

Вопрос

Должно быть что-то, что я 'Мне не хватает NSCollectionViewLayout и Auto Layout, но я не нашел в документации ничего, что указывало бы на это.

Я пытался вручную вызывать эти методы в различных точках жизненного цикла представления коллекции, но ничегоудалось правильно запустить макет для настройки его атрибутов caclulated.

Есть ли свойство, которое необходимо установить в представлении коллекции, его макете или элементах, указывающих, что должен вызываться preferredLayoutAttributesFitting(_:)?Поддерживается ли автоматическое расположение только для подклассов NSCollectionViewFlowLayout и NSCollectionViewGridLayout?Или я неправильно понимаю жизненный цикл экземпляра NSCollectionViewLayout?

1 Ответ

0 голосов
/ 26 сентября 2018

У меня та же проблема, это мое решение, оно отлично работает.Добавьте приведенный ниже код в подкласс UICollectionViewCell.

override func awakeFromNib() {

    super.awakeFromNib()

    self.contentView.translatesAutoresizingMaskIntoConstraints = false

    let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
    let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
    let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
    let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
    NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
}
...