Open MaxKlyukin opened 7 months ago
Hi @MaxKlyukin, thanks for pointing that out. I totally missed the scrolling issue. I'm on it - will check it out and see what I can do to make the scrolling more user-friendly.
+1
It would be great if the autoscroll can be suspended when the user selects a text or scrolls manually. The autoscroll later can be continued when a new message is sent by the user.
I think I was able to get something that might work from ChatGPT for a messaging app. The idea is to keep track of if the user scrolled to the bottom manually and only then do the autoscroll.
import SwiftUI
struct Message: Identifiable {
var id = UUID()
var text: String
}
struct ChatView: View {
@State private var messages: [Message] = [
Message(text: "Hello"),
Message(text: "How are you?"),
Message(text: "Nice to meet you!"),
]
@State private var isScrolledToBottom = true
var body: some View {
VStack {
ScrollViewReader { scrollViewProxy in
ScrollView {
VStack(spacing: 10) {
ForEach(messages) { message in
Text(message.text)
.padding(8)
.background(Color.blue)
.foregroundColor(.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.id(message.id)
}
}
.padding()
.onChange(of: messages) { _ in
// Automatically scroll to the bottom only if the user is already at the bottom
if isScrolledToBottom {
withAnimation {
scrollViewProxy.scrollTo(messages.last?.id, anchor: .bottom)
}
}
}
.onAppear {
// Set initial scroll position to the bottom
scrollViewProxy.scrollTo(messages.last?.id, anchor: .bottom)
}
.onTapGesture {
// User manually scrolled, so disable automatic scrolling
isScrolledToBottom = false
}
.onEnded { _ in
// User finished scrolling, check if at the bottom
let currentOffset = scrollViewProxy.contentOffset.y
let maxY = scrollViewProxy.frame(in: .local).maxY
isScrolledToBottom = currentOffset > maxY - 10 // Consider a small threshold
}
}
}
// Example: Add a new message
Button("Add Message") {
let newMessage = Message(text: "New message")
messages.append(newMessage)
}
.padding()
}
.navigationTitle("Chat")
}
}
struct ChatView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ChatView()
}
}
}
The problem: It's hard to read a response while the app automatically scrolls to the last line in the response.
Can you please look into making user scrolling possible while generation is in progress?