You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS17+下SwiftUI LazyVStack收起键盘后卡顿问题求助

iOS 17+ LazyVStack 收起键盘后卡顿滞留问题

问题详情

  • 红色背景的LazyVStack在收起键盘后出现卡顿滞留,蓝色背景为外层的ScrollView
  • 触发场景:弹出键盘后滚动到列表最后一项,再收起键盘
  • 已排除原因:并非键盘内边距问题(已移除键盘感知修饰符并验证)
  • 复现条件:仅当列表内容尺寸存在差异(如包含长消息)时出现,内容尺寸统一时无异常
  • 版本差异:iOS 16及以下版本无此问题,项目最低部署版本为iOS 14

相关代码

var body: some View {
        ScrollViewReader { scrollProxy in
            ScrollView(showsIndicators: false) {
                LazyVStack(spacing: 0) {
                    ForEach(messagesViewModel.messages.indices, id: \.self) { index in
                        let message = messagesViewModel.messages[index]
                        let isBeginningOfSection = message.messageIndex == messagesViewModel.messages.first?.messageIndex
                        
                        chatMessageView(for: message, isBeginningOfSection: isBeginningOfSection )
                            .id(message.messageIndex)
                            .padding(.bottom, messagesViewModel.bogeyChatSuggestions != nil ? 0 : index == messagesViewModel.messages.count - 1 ? 65 : 0)
                            .onAppear {
                                print("Message Appaered: \(message)")
                            }
                    }
                    
                    // Bogey Chat Suggestions
                    if let bogeySuggestions = messagesViewModel.bogeyChatSuggestions {
                        BogeySuggestionsView(
                            bogeySuggestions: bogeySuggestions,
                            onCloseAction: {
                                messagesViewModel.bogeyChatSuggestions = nil
                            },
                            onSendSuggestionAction: { message in
                                messagesViewModel.sendMessage(suggestionMessage: message)
                                messagesViewModel.bogeyChatSuggestions = nil
                            },
                            onTeetimeBookingAction: {
                                viewControllerHolder.dismiss(animated: false) {
                                    NotificationCenter.default.post(name: Notification.Name.navigateToGolfCourseScreen, object: nil)
                                }
                            }
                        )
                        .id(bogeySuggestions.id)
                    }
                }
                .background(Color.red.opacity(0.5))
                .padding(.top, 25)
                .padding(.bottom,  messagesViewModel.bogeyChatSuggestions != nil ? 65 : 0)
            }
            .background(Color.blue.opacity(0.8))
            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
                if let lastMessage = messagesViewModel.messages.last  {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.8, execute: {
                        scrollProxy.scrollTo(lastMessage.messageIndex, anchor: .bottom)
                        print("Scrolledddd to last message Index: \(lastMessage.messageIndex)")
                    })
                }
            }
            .onAppear {
                messageCount = messagesViewModel.messages.count
                print("OnAppear MessageCount: \(messageCount)")
                guard messageCount > 0 else { return }
                
                if let lastMessage = messagesViewModel.messages.last  {
                    scrollProxy.scrollTo(lastMessage.messageIndex, anchor: .bottom)
                    
                    if authorId != lastMessage.author {
                        guard
                            let messageSid = lastMessage.sid,
                            let conversationSid = lastMessage.conversationSid
                        else { return }
                        Task {
                            await messagesViewModel.updateMessageReadStatus(messageSid: messageSid, conversationSid: conversationSid, participantSid: authorId)
                        }
                    }
                }
                
                Task {
                    await messagesViewModel.getBogeySuggestion(senderId: self.authorId, recieverId: self.recipientId, conversationSid: self.conversationSid, profileMode: self.profileMode)
                }
            }
            .onChange(of: messagesViewModel.messages) { newValue in
                if let lastMessage = messagesViewModel.messages.last {
                    messagesViewModel.bogeyChatSuggestions = nil
                    scrollProxy.scrollTo(lastMessage.messageIndex, anchor: .bottom)
                    
                    if authorId != lastMessage.author  {
                        guard
                            let messageSid = lastMessage.sid,
                            let conversationSid = lastMessage.conversationSid
                        else { return }
                        Task {
                            await messagesViewModel.updateMessageReadStatus(messageSid: messageSid, conversationSid: conversationSid, participantSid: authorId)
                        }
                    }
                }
            }
            .onChange(of: messagesViewModel.bogeyChatSuggestions) { newValue in
                if let bogeySuggestions = newValue {
                    withAnimation {
                        scrollProxy.scrollTo(bogeySuggestions.id, anchor: .bottom)
                    }
                }
            }
        }
    }

问题截图

问题截图

内容的提问来源于stack exchange,提问作者Sins97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 02:43:14