63. Удобный скролл в iOS 17

63. Удобный скролл в iOS 17

Oleg991

В iOS 17 у нас появились классные модификаторы, позволяющие гибко настроить поведение скролла. В этой статье посмотрим на scrollTargetLayout и scrollTargetBehavior.

Сделаем такой экран:

Демо скролла с доводкой

На демо видно эффект доводки: когда мы тянем элемент, а потом отпускаем, и скролл автоматически ставит нужный элемент в дефолтное положение на экране.

Дополнительно по кнопкам внизу экрана можно быстро перейти к первому/последнему элементу.

Код для экрана

public struct ScrollTargetExample: View {
  /// Идентификатор текущего элемента для управления скроллом
  @State private var scrollID: String?
  let items: [Item]
   
  public var body: some View {
    if #available(iOS 17.0, *) {
      VStack(spacing: 20) {
        scrollContentView
        buttonStack
      }
    } else {
      Text("Заглушка для ScrollView без крутых фичей")
    }
  }
   
  @available(iOS 17.0, *)
  private var scrollContentView: some View {
    ScrollView(.horizontal) {
      LazyHStack(spacing: 12) {
        ForEach(items) { item in
          Text(item.title)
            .foregroundStyle(.white)
            .font(.title.bold())
            .frame(width: 300, height: 150)
            .background {
              RoundedRectangle(cornerRadius: 16)
                .fill(
                  .linearGradient(
                    colors: item.colors,
                    startPoint: .leading,
                    endPoint: .trailing
                  )
                )
            }
        }
      }
      .scrollTargetLayout() // 1 <- обязательно для "доводки"
    }
    .scrollIndicators(.hidden)
    .scrollTargetBehavior(.viewAligned) // 2 <- обязательно для "доводки"
    .safeAreaPadding(.horizontal, 20) // 3 <- для отступов по бокам от безопасной зоны
    .scrollPosition(id: $scrollID) // 4 <- для скролла к элементу
  }
   
  private var buttonStack: some View {
    HStack {
      Button("< К первому") {
        withAnimation {
          scrollID = items.first?.id
        }
      }
      .disabled(scrollID == items.first?.id || scrollID == nil)
      Spacer()
      Button("К последнему >") {
        withAnimation {
          scrollID = items.last?.id
        }
      }
      .disabled(scrollID == items.last?.id)
    }
    .padding(.horizontal)
  }
}

extension ScrollTargetExample {
  struct Item: Identifiable {
    let id = UUID().uuidString
    let title: String
    let colors: [Color]
  }
}
Если попробовать убрать один из модификаторов (1) или (2), то эффекта доводки не будет

Заключение

С каждой новой версией iOS становится все удобнее работать со SwiftUI, и в iOS 17 классно прокачали ScrollView, что позволяет достигать результатов не хуже, чем раньше с UICollectionView.

Код для этой статьи можно посмотреть тут, а другие статьи - тут.


Report Page