Post

Replies

Boosts

Views

Activity

scrollPosition(id:anchor:) freeze UI when show/hide keyboard
Hello ! This will be my first blog post. I hope I will find the solution. So, I try to use the new iOS 17+ API for ScrollView. I have an array of messages that I want to show in scroll view. And I need to scroll to bottom when I tap to Send button. When I use scrollPosition(id:anchor:), it freeze the UI. The link to the screencast to demonstrate. I think the problem might be the keyboard when it shows and hides. But I can't understand what can I do. struct ChatView: View { @ObservedObject var viewModel: CoachViewModel @State private var scrollTo: Message.ID? var body: some View { ScrollView { LazyVStack { ForEach(viewModel.messages) { message in MessageView(viewModel: viewModel, message: message) } } .scrollTargetLayout() } .scrollPosition(id: $scrollTo) .background(.primaryBackground) .onChange(of: viewModel.scrollToBottom) { if $1, let lastMessage = viewModel.messages.last { withAnimation { scrollTo = lastMessage.id } viewModel.scrollToBottom = false } } } } struct Message: Identifiable, Hashable { let id: UUID let author: MessageAuthor let text: String } final class CoachViewModel: ObservableObject { @Published var messageTextInput = "" @Published var scrollToBottom = false @Published var messages: [Message] = [...] // ... more code ... func sendMessage() { messages.append( .init( id: .init(), author: .user, text: messageTextInput ) ) messageTextInput.removeAll() scrollToBottom = true } } struct CoachView: View { @StateObject private var viewModel = CoachViewModel() @State private var isSearching = false var body: some View { VStack(spacing: 0) { Group { CoachTitleView(viewModel: viewModel, isSearching: $isSearching) ChatView(viewModel: viewModel) } .onTapGesture { UIApplication.shared.endEditing() } if isSearching { MatchboxView(viewModel: viewModel) } else { InputTextFieldView(viewModel: viewModel) } } } }
0
0
270
Jun ’24