SwiftUI automatically scroll to bottom in ScrollView (Bottom first)

后端 未结 2 916
长情又很酷
长情又很酷 2021-02-20 02:54

My problem is that i have (in SwiftUI) a ScrollView with an foreach inside. Know when the foreach loads all of my entries i want that the last entry is focused.

I did so

相关标签:
2条回答
  • 2021-02-20 02:57

    Solution for iOS14 with ScrollViewReader

    in iOS14 SwiftUI gains a new ability. To be able to scroll in a ScrollView up to a particular location. There is a new type called ScrollViewReader which works just like Geometry Reader.

    The code below will scroll to the last item in your View. I reused your code adding some color for better visualisation. So this is your struct for 'Entry' I guess:

    struct Entry {
        static var index = 0
        var name = "Entry number "
        
        func getName() -> String {
             Entry.index += 1
             return self.name + "\(Entry.index)"
        }
    }
    

    And the main ContentView:

    struct ContentView: View {
        let colors: [Color] = [.red, .blue, .green]
        var entries: [Entry] = Array(repeating: Entry(), count: 10)
    
        var body: some View {
            ScrollView {
                ScrollViewReader { value in
                                
                    ForEach(0..<entries.count) { i in
                        Text(self.entries[i].getName())
                            .frame(width: 300, height: 200)
                            .background(colors[i % colors.count])
                            .padding(.all, 20)
                    }
                    .onAppear {
                        value.scrollTo(entries.count - 1, anchor: .center)
                    }
                }
            }
        }
    }
    

    Try to run this in the new version of SwiftUI announced at WWDC20. I think it is a great enhancement.

    0 讨论(0)
  • 2021-02-20 03:13

    Scrolling to the bottom on change

    I don't have enough reputation to post a comment yet, so here you go @Dam and @Evert

    To scroll to the bottom whenever the number of entries in your ForEach changes you can also use the same method with a ScrollViewReader, as mentioned in the answer above, by adding the view modifier onChange like so:

    struct ContentView: View {
        let colors: [Color] = [.red, .blue, .green]
        var entries: [Entry] = Array(repeating: Entry(), count: 10)
    
        var body: some View {
            ScrollView {
                ScrollViewReader { value in
                                
                    ForEach(0..<entries.count) { i in
                        Text(self.entries[i].getName())
                            .frame(width: 300, height: 200)
                            .background(colors[i % colors.count])
                            .padding(.all, 20)
                    }
                    .onChange(of: entries.count) { _ in
                        value.scrollTo(entries.count - 1)
                    }
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题