我试图以编程方式滚动到ScrollView中的特定Y位置,当单击按钮时,如何设置ScrollView位置?
ScrollView
ScrollView { Button(action: { }) { Text("Sign In").fontWeight(.heavy) } }
字符串我想这个按钮的行动,以访问和更改ScrollView的立场。
oyjwcjzk1#
SwiftUI 2.0从iOS 14开始,可以使用ScrollViewReader(即ScrollView容器中的某些特定视图可以分配标识符并通过ScrollViewProxy.scrollTo分配给该视图),如下面的示例所示使用Xcode 12b测试。
ScrollViewReader
ScrollViewProxy.scrollTo
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 !! } } } } }
字符串
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会将你的物品的中心放在屏幕的中心,等等(至少这是我目前对它的理解)在理解了这一点之后,我终于能够提出以下代码,到目前为止,对我来说是有效的:
.scrollTo("id", anchor: .center)
UnitPoint(x:y:)
y: 300
UnitPoint
y: 0.4
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位置会如此复杂,但希望这能帮助到一些人。
2条答案
按热度按时间oyjwcjzk1#
SwiftUI 2.0
从iOS 14开始,可以使用
ScrollViewReader
(即ScrollView容器中的某些特定视图可以分配标识符并通过ScrollViewProxy.scrollTo
分配给该视图),如下面的示例所示使用Xcode 12b测试。
字符串
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会将你的物品的中心放在屏幕的中心,等等(至少这是我目前对它的理解)在理解了这一点之后,我终于能够提出以下代码,到目前为止,对我来说是有效的:
字符串
现在,你仍然需要给你的视图给予一个id,你还需要知道你的视图的高度,所以对于动态视图,你需要读取和存储视图的框架。你可以找到这个here的一个示例用法,这就是为什么我首先需要这个,当它被键盘隐藏时滚动到一个特定的输入。
作为一种变通方法/技巧,如果你不想处理获取视图高度的问题,你可以设置一个高度为1的不可见视图,每当你想滚动到一个位置时,就使用这个视图:
型
SwiftUI的很多设计决策都是非常糟糕的,没有理由滚动到一个特定的x,y位置会如此复杂,但希望这能帮助到一些人。