ScrollView使用SwiftUI获取/设置滚动位置

0ejtzxu1  于 2024-01-05  发布在  Swift
关注(0)|答案(2)|浏览(374)

我试图以编程方式滚动到ScrollView中的特定Y位置,当单击按钮时,如何设置ScrollView位置?

ScrollView {
 Button(action: {

 }) {
    Text("Sign In").fontWeight(.heavy)        
 }
}

字符串
我想这个按钮的行动,以访问和更改ScrollView的立场。

oyjwcjzk

oyjwcjzk1#

SwiftUI 2.0
从iOS 14开始,可以使用ScrollViewReader(即ScrollView容器中的某些特定视图可以分配标识符并通过ScrollViewProxy.scrollTo分配给该视图),如下面的示例所示
使用Xcode 12b测试。

struct DemoScrollToView: View {
    var body: some View {
        ScrollView {
            ScrollViewReader { sp in     // << here !!
                Button(action: {
                    withAnimation {
                        sp.scrollTo(80)            // << here !!
                    }
                }) {
                    Text("Sign In").fontWeight(.heavy)
                }

                ForEach(0..<100) { i in
                    Text("Item \(i)").padding().id(i)       // << here !!
                }
            }
        }
    }
}

字符串

cyej8jka

cyej8jka2#

好吧,最初我认为滚动到特定的y位置是不可能的。但几个小时后,我意识到.scrollTo("id", anchor: .center)实际上接受UnitPoint(x:y:)
当我发现这一点时,我以为我终于弄明白了这一点,但很快意识到你不能像y: 300那样直接将y的绝对值传递给UnitPoint,而是接受0到1的比率。
所以我想我可以传递y: 0.4来表示“滚动到屏幕高度的40%”,但是不行。这个值是项目和屏幕高度的比率(或者ScrollView的高度?不是很确定tbh),这意味着,0.8的y将把你的项目的80%标记,放在屏幕高度的80%标记上,y值为0.5会将你的物品的中心放在屏幕的中心,等等(至少这是我目前对它的理解)
在理解了这一点之后,我终于能够提出以下代码,到目前为止,对我来说是有效的:

func scrollTo(y: CGFloat, scrollProxy: ScrollViewProxy, containerId: String, itemHeight: CGFloat) {
    let screenHeight = UIScreen.main.bounds.height
    let yRatio = y / screenHeight
    let anchor = (yRatio * screenHeight) / (screenHeight - itemHeight)
    
    withAnimation {
        scrollProxy.scrollTo(containerId, anchor: UnitPoint(x: 0.5, y: anchor))
    }
}

字符串
现在,你仍然需要给你的视图给予一个id,你还需要知道你的视图的高度,所以对于动态视图,你需要读取和存储视图的框架。你可以找到这个here的一个示例用法,这就是为什么我首先需要这个,当它被键盘隐藏时滚动到一个特定的输入。
作为一种变通方法/技巧,如果你不想处理获取视图高度的问题,你可以设置一个高度为1的不可见视图,每当你想滚动到一个位置时,就使用这个视图:

ScrollView {
    // ...

    Spacer().frame(width:1,height:1).id("scrollToPosition")

    // ...
}


SwiftUI的很多设计决策都是非常糟糕的,没有理由滚动到一个特定的x,y位置会如此复杂,但希望这能帮助到一些人。

相关问题