1

I want to scroll to the bottom of my scroll view when another comment is added to the chat. I tried using ScrollViewReader but it is not scrolling to the bottom. I'm checking if the comments are adding in the onChange method it is triggering and printing out the last index of the array. I am not sure why it wouldn't be working then

class TakeCommentViewModel: ObservableObject {
    
    @Published var comments = [TakeComment]()
}

in the SwiftUI File:

@ObservedObject var model = TakeCommentViewModel()

var commentsList: some View {
        ScrollViewReader { proxy in
            ScrollView {
                VStack {
                    TakeTopView(dismissAction: dismissAction, take: take)
                    ForEach(model.comments) { comment in
                        TakeCommentView(comment: comment, viewModel: model)
                    }
                }
            }
            .onAppear {
                model.fetchComments(takeID: take.id)
                IQKeyboardManager.shared.enable = false
                proxy.scrollTo(model.comments.count - 1, anchor: .top)
            }
            .onDisappear {
                if model.listener != nil {
                    model.listener.remove()
                }
                IQKeyboardManager.shared.enable = true
            }
            .onChange(of: model.comments.count, perform: { value in
                proxy.scrollTo(model.comments.count - 1)
                let _ = print("CHANGED: \(model.comments.count)")

            })
        }   
    }
3
  • The ScrollViewReader probably expects an id. Does it work if you do if let last = model.comments.last { proxy.scrollTo(last.id) }? Commented Mar 4, 2022 at 4:08
  • as @jnpdx mentioned, ScrollViewReader expects an id, the scrollTo uses id not index, so you may want to add id after TakeTopView(dismissAction: dismissAction, take: take) and try again Commented Mar 4, 2022 at 4:49
  • I believe the ForEach will append the id automatically Commented Mar 4, 2022 at 7:10

1 Answer 1

4

Since you are using scrollTo based on index, you need to set index as id.

ForEach(Array(model.comments.enumerated()), id: \.offset) { index, comment in
    TakeCommentView(comment: comment, viewModel: model)
        .id(index)  // ForEach might set id automatically, but I added this just in case
}
Sign up to request clarification or add additional context in comments.

1 Comment

This did the trick for me, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.