May 30, 2024

69. Вертикальный список в SwiftUI

В SwiftUI есть несколько способов создания вертикальных списков, каждый из которых имеет свои преимущества и недостатки. В этой статье расскажу про три основных метода: ScrollView + VStack, ScrollView + LazyVStack и List.

Мобильное приложение с вертикальным списком

ScrollView + VStack

ScrollView + VStack — это самый неэффективный способ создания списков из перечисленных, потому что он загружает все элементы списка сразу, что может привести к медленному отображению и высокой нагрузке на память. В отличие от LazyVStack, VStack сразу загружает в память все элементы, которые содержит, что может привести к заметным тормозам на больших списках, и речь не про сотни элементов, а про десятки.

Преимущество у такого подхода одно - работает с iOS 13 💁‍♂️

Пример кода

ScrollView {
    VStack(spacing: 16) {
        ForEach(items) { item in
            Text(item.title)
        }
    }
}

ScrollView + LazyVStack

ScrollView + LazyVStack — это более эффективный способ создания списков. Он догружает элементы списка только когда они становятся видимыми на экране, что обеспечивает более эффективное использование памяти и улучшает производительность. Это особенно полезно при работе с большими списками, когда не все элементы могут быть отображены на экране одновременно.

Важно: LazyVStack не умеет переиспользовать ячейки, но умеет загружать их по мере их появления на экране, при этом он требует iOS 14.

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

Пример кода

ScrollView {
    LazyVStack(spacing: 16) {
        ForEach(items) { item in
            Text(item.title)
        }
    }
}

List

List — это стандартный способ создания списков в SwiftUI (ячейки переиспользуются), доступный прямо с iOS 13. Он позволяет быстро настроить стиль отображения списка при помощи модификатора listStyle (эти стили используются в большинстве стандартных приложений в iOS).

List из коробки поддерживает жесты свайпа c iOS 15 через модификатор swipeActions, а жест удаления - и вовсе с iOS 13 через модификатор onDelete.

Также List поддерживает модификатор refreshable с iOS 15, в отличие от ScrollView, с которым refreshable работает только от iOS 16.

Однако, некоторые настройки для List доступны только с iOS 15 и выше, например: listRowSeparator, listSectionSeparator, headerProminence, и другие - поэтому зачастую проще использовать ScrollView + LazyVStack, если нужно поддерживать iOS 14.

К тому же, List все еще имеет свои баги/неожиданные моменты: раз, два, три (список можно продолжать 😁).

Пример кода

List(items) { item in
    Text(item.title)
}

Заключение

Каждый из перечисленных методов создания списков в SwiftUI имеет свои преимущества/недостатки, которые желательно знать, чтобы в зависимости от конкретной задачи и минимального таргета iOS без труда выбрать подходящий.

Для пет-проекта можно смело использовать List, а для рабочих задач лучше сначала посмотреть в сторону ScrollView + LazyVStack.

Другие мои статьи можно почитать тут.