简体   繁体   English

SwiftUI 在视图层次结构中向上传递滚动位置

[英]SwiftUI pass scroll location up the View hierarchy

I have a SwiftUI application.我有一个 SwiftUI 应用程序。 It has a ScrollView and a Text and I want the Text to display the position of the elements in the ScrollView.它有一个 ScrollView 和一个 Text,我希望 Text 显示 ScrollView 中元素的 position。

struct LinkedScrolling: View {
    @State var scrollPosition: CGFloat = 0

    var body: some View {
        VStack {
            Text("\(self.scrollPosition)")
            ScrollContent(scrollPosition: self.$scrollPosition)
        }
    }
}

This View contains the Text and the ScrollContent.此视图包含文本和滚动内容。 This is ScrollContent:这是滚动内容:

struct ScrollContent: View {
    @Binding var scrollPosition: CGFloat

    var body: some View {
        ScrollView(.horizontal) {
            GeometryReader { geometry -> AnyView in
                self.scrollPosition = geometry.frame(in: .global).minX

                let view = AnyView(HStack(spacing: 20) {
                        Rectangle()
                            .fill(Color.blue)
                            .frame(width: 400, height: 200)
                        Rectangle()
                            .fill(Color.red)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.green)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.orange)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.pink)
                            .frame(width: 400, height: 200)

                })
                return view
            }.frame(width: 5*400+4*20)
        }
    }
}

The State variable scrollPosition gets updated every time the elements in the ScrollView move.每次 ScrollView 中的元素移动时,State 变量scrollPosition都会更新。 When using the app in an iOS 14.2 Simulator, scrollPosition does not change and the console logs [SwiftUI] Modifying state during view update, this will cause undefined behavior.在 iOS 14.2 模拟器中使用该应用程序时,scrollPosition 不会更改,并且控制台会记录[SwiftUI] Modifying state during view update, this will cause undefined behavior. . .

What really confuses me, is that it works in the Xcode preview canvas and the State variable and the Text change like I want them to.真正让我感到困惑的是,它可以在 Xcode 预览 canvas 和 State 变量和我想要的文本更改中工作。

Is it possible to change the State variable this way?是否可以通过这种方式更改 State 变量? If yes, how can I try to make it work on the Simulator?如果是,我该如何尝试使其在模拟器上运行? If no, is there any other way to achieve my goal?如果没有,还有其他方法可以实现我的目标吗?

Thank you for your help!谢谢您的帮助!

You can use DispatchQueue.main.async .您可以使用DispatchQueue.main.async

DispatchQueue.main.async {
    self.scrollPosition = geometry.frame(in: .global).minX
}

Or better way is to use .onReceive或者更好的方法是使用.onReceive

Like this像这样

struct ScrollContent: View {
    @Binding var scrollPosition: CGFloat

    var body: some View {
        ScrollView(.horizontal) {
            GeometryReader { geometry in
                HStack(spacing: 20) {
                        Rectangle()
                            .fill(Color.blue)
                            .frame(width: 400, height: 200)
                        Rectangle()
                            .fill(Color.red)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.green)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.orange)
                            .frame(width: 400, height: 200)
                        Rectangle()
                        .fill(Color.pink)
                            .frame(width: 400, height: 200)

                }.onReceive(Just(geometry), perform: { _ in //<-- Here
                    self.scrollPosition = geometry.frame(in: .global).minX
                })
            }.frame(width: 5*400+4*20)
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM