Прокрутка внутри ScrollView в SwiftUI

В гигантском ScrollView я хочу разместить Circles и прокручивать их так, чтобы при прокрутке они оказывались в середине экрана один за другим.

Я могу расположить круги, используя .position, .offset или .padding. Я разместил их (300300) вдали друг от друга, чтобы ни один из них не отображался на экране при загрузке представления.

Когда я прокручиваю до тех, которые расположены с помощью .position или .offset, ScrollView прокручивается в верхний левый угол. .offset прокручивается со вставкой, .position полностью. Когда я прокручиваю до того, что расположен с .padding, он не центрируется.

Что я здесь делаю неправильно? Почему ни одна из моих трех попыток не прокручивается так, чтобы рассматриваемый круг был помещен в середину ScrollView?

      struct CanvasTester: View {
    
    @State var i = 0
    
    var body: some View {
        ZStack(alignment: .topLeading) {
            ScrollViewReader { scrollView in
                ScrollView([.horizontal, .vertical]) {
                    ZStack(alignment: .topLeading) {
                        Spacer()
                            .frame(width: 4096, height: 4096)
                            .background(Color.yellow)
                            .task {
                                @Sendable func f() {
                                    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                                        withAnimation {
                                            scrollView.scrollTo("circle\(i+1)", anchor: .center)
                                            self.i = (self.i + 1) % 3
                                        }
                                        f()
                                    }
                                }
                                f()
                            }
                        
                        Circle()
                            .stroke(Color.blue, lineWidth: 4)
                            .frame(width: 44, height: 44)
                            .offset(x: 1500, y: 1500)
                            .id("circle1")

                        Circle()
                            .stroke(Color.green, lineWidth: 4)
                            .frame(width: 44, height: 44)
                            .position(x: 1800, y: 1800)
                            .id("circle2")

                        Circle()
                            .stroke(Color.red, lineWidth: 4)
                            .frame(width: 44, height: 44)
                            .padding([.top, .leading], 2100)
                            .id("circle3")
                    }
                }
            }

            Text("#\(i+1)")

        }
    }
}

Быстрый просмотр кода: у меня есть ScrollReader, инкапсулирующий ScrollView, который прокручивается в обоих направлениях и имеет размер 4096x4096. Он имеет желтый фон, который при рисовании запускает функцию, которая каждую секунду прокручивает представление с идентификатором «circle1», «circle2» или «circle3». Затем следуют три круга с этими метками и, наконец, метка I в верхнем левом углу, чтобы указать, какой номер цвета имеет идентификатор.

0 ответов

Другие вопросы по тегам