Создавайте современные заголовки для вашего UITableView

В последние годы мобильные приложения становятся все более популярными благодаря использованию больших изображений в качестве заголовков для списков. Как вы, возможно, знаете, изображение стоит тысячи слов, поэтому большая фотография может помочь пользователю лучше понять содержимое экрана. Конечно, большая часть пользовательского опыта обеспечивается большим ручным взаимодействием с программными компонентами, и приятнее и кажется более естественным имитировать какое-то гибкое поведение в пользовательском интерфейсе, и кто-то когда-то в прошлом сказал: «Было бы здорово, если бы изображение могло растягиваться, становясь все больше и больше, когда пользователь опускает стол? Не было бы еще круче, если бы это красивое большое изображение ускользало, когда пользователь прокручивал этот список вверх?», и так родились растягиваемые заголовки!

За свою карьеру в iOS я видел много разных реализаций этих эффектов… некоторые простые, некоторые трудно воспроизводимые, некоторые линейные, некоторые очень сложные. В этой статье я покажу вам свой путь. 😉

На видео вы можете увидеть окончательный результат:

Эффект достигается с помощью очень простого трюка.

Вместо того, чтобы помещать заголовок в UITableView view, просто используйте UIImageView и поместите его под таблицу. Да прямо под столом! Ограничьте изображение по бокам и сверху и задайте ограничение по высоте в соответствии с вашими потребностями. Придайте изображению режим содержания соотношение сторон. Это действительно важно. Без этого вы не будете испытывать масштабирование изображения, когда пользователь тянет стол.

Затем добавьте UITableView поверх изображения и добавьте четыре боковых ограничения в безопасные области вашего контроллера. Сделайте прозрачный фон. Это понадобится для следующего прохождения.

Для последнего прохода в раскадровке добавьте UIView в таблицу в качестве заголовка и задайте для нее прозрачный цвет фона. Задайте значение высоты этого вида, которое будет равно высоте, используемой для ограничения высоты в предыдущем примере, в нашем примере это было 260.

Излишне говорить, что вы должны добавить в свою таблицу ячейку-прототип.

Теперь давайте перейдем к нашему viewController. Создайте два IBOutlet, один для таблицы и другой для ограничения высоты растягиваемого изображения. Затем добавьте переменную CGFloat для записи начального эталонного значения самого ограничения, позже мы увидим его значение:

@IBOutlet weak var cnstHeaderHeight: NSLayoutConstraint!
@IBOutlet weak var tableView: UITableView!
var refConstraintValue: CGFloat?

Для этого примера я создал простой список UUID, например:

var items = (0…30).map { _ in UUID().uuidString }

Если вас интересует использование операторов map, взгляните на другую статью, которую я недавно написал:



Пришло время добавить наши delegate и datasource в стартовую последовательность нашего контроллера:

Отлично, теперь давайте реализуем очень простой UITableViewDataSource:

Хорошо, наш контроллер готов, но, как вы можете себе представить, на заголовке нет никаких эффектов.
Как вы, возможно, знаете, UITableViews происходит от UIScrollViews, но, возможно, вы не знаете, что UITableViewDelegate происходит от UIScrollViewDelegate, поэтому мы можем реализовать делегат и используйте его, чтобы прочитать положение прокручиваемой области в таблице по вертикальной оси. Используя это значение, мы собираемся изменить значение высоты изображения заголовка в реальном времени:

  • Строка 5: как указано в начале статьи, если установлено значение nil, эталонное значение ограничения высоты. Позже он будет использован для некоторых расчетов.
  • Строка 12: пока высота выше нуля, я использую ее как ограничение по высоте, в противном случае я устанавливаю ее равной нулю, поскольку размер не может быть отрицательным. Как видите, начальное значение со смещением по оси y, равным нулю, дает исходную высоту, то есть само refConstraintValue. Если finalHeight становится больше эталонного значения, изображение становится больше. Если становится меньше, изображение сжимается, сохраняя центральное положение в представлении, как показано в исходном видео.

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

Этот эффект делается простым вызовом в конце scrollViewDidScroll следующей функции:

Где navView — это наше исчезающее представление навигации, а 150, 62 — магические числа (никогда их не используйте…), выбранные эмпирическим путем для создания приятного эффекта. Я также использовал функцию фиксации, чтобы ограничить значение от 0 до 1.

Надеюсь, вам понравилась эта статья, если да, пожалуйста, хлопните в ладоши.
Если эта статья была вам полезна, не стесняйтесь предложить мне кофе и позвольте мне создать больше классного контента и статей.

Наслаждайтесь кодированием!