October 21, 2023
37. Делаем модификатор с кастомным индикатором загрузки
В этой статье покажу простой способ сделать модификатор с анимированной сменой состояния загрузки, блокирующий контент от нажатий на время загрузки (пока ждем ответ сервера, например).
Для модификатора в первую очередь нам понадобится вьюшка с индикатором загрузки:
/// Вьюшка с анимированным индикатором загрузки
private struct LoadingIndicatorView: View {
@State private var isAnimating = false
var body: some View {
Image(.loadingIndicator) // Картинка из ассетов проекта
.resizable()
.frame(width: 50, height: 50)
.foregroundStyle(.white)
.rotationEffect(Angle(degrees: isAnimating ? 360 : 0))
.animation(
.linear(duration: 2.0).repeatForever(autoreverses: false),
value: isAnimating
)
.onAppear { isAnimating = true }
}
}
Кстати, в Xcode 15 картинки из ассетов генерируются автоматически:
Теперь можно сделать сам модификатор:
/// Модификатор для отображения индикатора загрузки
///
/// Делает контент недоступным для нажатия в состоянии загрузки
struct LoadingIndicatorModifier: ViewModifier {
let isLoading: Bool
func body(content: Content) -> some View {
ZStack {
content
.opacity(isLoading ? 0.5 : 1)
.disabled(isLoading)
if isLoading {
LoadingIndicatorView()
}
}
.animation(.default, value: isLoading)
}
}
Все просто: если isLoading = true, то показываем прозрачный контент, иначе - обычный. Также делаем контент недоступным и анимируем изменения при смене isLoading.
Для удобства применения модификатора можно сделать доп. метод:
extension View {
func loadingOverlay(if isLoading: Bool) -> some View {
modifier(LoadingIndicatorModifier(isLoading: isLoading))
}
}
struct LoadingIndicatorModifierExample: View {
@State private var isLoading = false
var body: some View {
Color.black.ignoresSafeArea()
.overlay {
Button("Начать загрузку") {
isLoading = true
}
.font(.title.bold())
.tint(.yellow)
}
.loadingOverlay(if: isLoading)
}
}
Если хочется, вместо LoadingIndicatorView можно использовать стандартный ProgressView.
Код для этой статьи можно посмотреть тут, а другие статьи - тут.