Ros*_*ipe 5 scrollview swiftui
我有一个固定高度的 ScrollView,其中包含一个 Text(),它不断从我的 viewModel 中更新。\n如果文本太多而无法一次查看,即我需要滚动才能看到文本的结尾,我\xe2 \x80\x99d 喜欢它自动滚动,这样我总是能看到文本的结尾。
\n那可能吗?
\n ScrollView {\n Text(vm.text)\n .frame(minWidth: 20, alignment: .leading)\n\n }\n .frame(height: 200)\nRun Code Online (Sandbox Code Playgroud)\n注意:这是我的问题的一个非常简化的版本。在我的应用程序中,有时文本没有更新,但确实需要可滚动。
\n我尝试过scrollViewReader \xe2\x80\xa6 类似的东西:
\n ScrollView {\n ScrollViewReader() { proxy in\n Text(vm.text)\n .frame(minWidth: 20, alignment: .leading)\n Text("").id(0)\n }\n }\n .frame(height: 200)\nRun Code Online (Sandbox Code Playgroud)\n想要滚动到空文本,但我无法\xe2\x80\x99t 弄清楚如何触发
\nwithAnimation {\n proxy.scrollTo(0)\n }\nRun Code Online (Sandbox Code Playgroud)\n...我见过的所有示例都使用按钮,但我需要在文本更新时触发。
\n我已经通过@ChrisR修改了代码,并进行了修改,至少显示了我希望的scrollTo: 工作方式。它在 2 个几乎相同的具有不同 id 的视图之间切换(其中一个有一点点填充)
import SwiftUI
struct ContentView: View {
@State private var vmtext = "\n\n\n\nTest Text"
@State private var number = 0
@State private var id = 0
// timer change of text for testing
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
var body: some View {
ScrollViewReader { proxy in
ScrollView {
id == 0 ?
VStack {
Text(vmtext)
.padding(.top, 0)
.font(.title2)
.id(0)
}
:
VStack {
Text(vmtext)
.padding(.top, 1)
.font(.title2)
.id(1)
}
}
// react on change of text, scroll to end
.onChange(of: vmtext) { newValue in
print("onChange entered. id: \(id)")
proxy.scrollTo(id, anchor: .bottom)
}
}
.frame(height: 90, alignment: .center)
.frame(maxWidth: .infinity)
.border(.primary)
.padding()
// timer change of text for testing
.onReceive(timer) { _ in
if id == 0 { id = 1} else {id = 0}
number += 1
vmtext += " word\(number)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:似乎如果显示的文本视图的高度没有改变, proxy.scrollTo 就会被忽略。将填充设置为相同,黑客就会中断。
从 var vmtext 中删除“\n\n\n\n”可以打破黑客攻击。它们使文本视图的初始大小大于滚动视图窗口,因此可以立即滚动 - 或者其他:-)。如果您确实删除了它们,则在用手指进行初始滚动后,滚动将开始工作。
编辑:
这是一个没有填充和“\n\n\n\n” hack 的版本,它使用双旋转 hack。
import SwiftUI
struct ContentView: View {
@State private var vmtext = "Test Text"
@State private var number = 0
@State private var id = 0
// timer change of text for testing
let timer = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
var body: some View {
ScrollViewReader { proxy in
ScrollView {
Group {
id == 0 ?
VStack {
Text(vmtext)
.font(.title2)
.id(0)
}
:
VStack {
Text(vmtext)
.font(.title2)
.id(1)
}
}
.padding()
.rotationEffect(Angle(degrees: 180))
}
.rotationEffect(Angle(degrees: 180))
// react on change of text, scroll to end
.onChange(of: vmtext) { newValue in
withAnimation {
if id == 0 { id = 1 } else { id = 0 }
proxy.scrollTo(id, anchor: .bottom)
}
}
}
.frame(height: 180, alignment: .center)
.frame(maxWidth: .infinity)
.border(.primary)
.padding()
// timer change of text for testing
.onReceive(timer) { _ in
number += 1
vmtext += " word\(number)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果文本从视图顶部开始并且仅在文本填满视图时才滚动,就像 swiftui TextEditor 一样,那就太好了......并且 withAnimation 不起作用。
| 归档时间: |
|
| 查看次数: |
863 次 |
| 最近记录: |