[英]Swiftui Scrollview scroll to bottom of list
每次添加新項目時,我都試圖讓我的視圖滾動到項目列表的底部。 這是我的代碼,有人可以幫忙嗎?
ScrollView(.vertical, showsIndicators: false) {
ScrollViewReader{ value in
VStack() {
ForEach(0..<self.count, id:\.self) {
Text("item \($0)")
}
}.onChange(of: self.data.sampleCount, perform: value.scrollTo(-1))
}
}
您可以在列表底部添加一個 EmptyView 項目
ScrollView(.vertical, showsIndicators: false) {
ScrollViewReader{ value in
VStack() {
ForEach(0..<self.count, id:\.self) {
Text("item \($0)")
}
Spacer()
.id("anID") //You can use any type of value
}.onChange(of: self.data.sampleCount, perform: { count in
value.scrollTo("anID")
})
}
我們需要為ScrollView
我們想要滾動到的視圖提供id
。
這是解決方案的演示。 使用 Xcode 12.1 / iOS 14.1 測試
struct DemoView: View {
@State private var data = [String]()
var body: some View {
VStack {
Button("Add") { data.append("Data \(data.count + 1)")}
.padding().border(Color.blue)
ScrollView(.vertical, showsIndicators: false) {
ScrollViewReader{ sr in
VStack {
ForEach(self.data.indices, id:\.self) {
Text("item \($0)")
.padding().id($0) // << give id
}
}.onChange(of: self.data.count) { count in
withAnimation {
sr.scrollTo(count - 1) // << scroll to view with id
}
}
}
}
}
}
}
這是我的示例/解決方案。
var scrollView : some View {
ScrollView(.vertical) {
ScrollViewReader { scrollView in
ForEach(self.messagesStore.messages) { msg in
VStack {
OutgoingPlainMessageView() {
Text(msg.message).padding(.all, 20)
.foregroundColor(Color.textColorPrimary)
.background(Color.colorPrimary)
}.listRowBackground(Color.backgroundColorList)
Spacer()
}
// 1. First important thing is to use .id
//as identity of the view
.id(msg.id)
.padding(.leading, 10).padding(.trailing, 10)
}
// 2. Second important thing is that we are going to implement //onChange closure for scrollTarget change,
//and scroll to last message id
.onChange(of: scrollTarget) { target in
withAnimation {
scrollView.scrollTo(target, anchor: .bottom)
}
}
// 3. Third important thing is that we are going to implement //onChange closure for keyboardHeight change, and scroll to same //scrollTarget to bottom.
.onChange(of: keyboardHeight){ target in
if(nil != scrollTarget){
withAnimation {
scrollView.scrollTo(scrollTarget, anchor: .bottom)
}
}
}
//4. Last thing is to add onReceive clojure, that will add an action to perform when this ScrollView detects data emitted by the given publisher, in our case messages array.
// This is the place where our scrollTarget is updating.
.onReceive(self.messagesStore.$messages) { messages in
scrollView.scrollTo(messages.last!.id, anchor: .bottom)
self.scrollTarget = messages.last!.id
}
}
}
}
也可以看看我在 medium 上的文章。
https://mehobega.medium.com/auto-scrollview-using-swiftui-and-combine-framework-b3e40bb1a99f
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.