簡體   English   中英

Swiftui Scrollview 滾動到列表底部

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM