Шаги для воспроизведения:
- Я перехожу к MessageView с помощью NavigationDestination. Экран
показывает пустое пространство внизу, сдвигая MessageInputBar
вверх. - Если я отправлю приложение в фоновый режим и затем откройте его снова, зазор
исчезнет, и вид будет выглядеть нормально, как и ожидалось.
Я хотите устранить это странное пустое пространство и обеспечить, чтобы MessageInputBar всегда оставался в нормальном положении (аналогично тому, как он ведет себя в большинстве приложений чата).
Снимки экрана:
(Появляется пробел)

Странный пробел исчезает после повторного открытия приложения из режима переднего плана

(Странный пробел исчезает после повторного открытия приложения на переднем плане режим)
ChatsView.swift
Код: Выделить всё
struct ChatsView: View {
//Bla bla
.navigationDestination(isPresented: $isNavigatingToMessageView, destination: {
Group {
if let currentChatRoomId = webSocketManager.currentChatRoomId {
MessageView(
webSocketManager: webSocketManager,
chatRoomId: currentChatRoomId
)
}
}})
}
2- MessageView.swift
Код: Выделить всё
struct MessageView: View {
@Environment(\.colorScheme) var colorScheme
@Environment(\.dismiss) private var dismiss
@ObservedObject var webSocketManager: WebSocketManager
@ObservedObject private var messageViewModel: MessageViewModel
@State private var newMessage = ""
@State private var isNavigatingToProfileView: Bool = false
@State private var isKeyboardVisible: Bool = false
@State private var alertType: AlertType? = nil
let chatRoomId: String
let currentUserId = Auth.auth().currentUser?.uid
private var messages: [ChatMessage] {
guard let chatRoom = webSocketManager.chatRooms.first(where: { $0.id == chatRoomId }) else {
return []
}
return chatRoom.messages
}
init(webSocketManager: WebSocketManager, chatRoomId: String, isNavigatedFromProfile: Bool = false ) {
self.webSocketManager = webSocketManager
self.chatRoomId = chatRoomId
self.isNavigatedFromProfile = isNavigatedFromProfile
// Create a new instance of MessageViewModel for this specific chatroom
if let viewModel = webSocketManager.getMessageViewModel(for: chatRoomId) {
self._messageViewModel = ObservedObject(wrappedValue: viewModel)
} else {
self._messageViewModel = ObservedObject(wrappedValue: MessageViewModel())
}
print("MessageView init")
}
var body: some View {
GeometryReader { proxy in
VStack(spacing:0) {
ScrollViewReader { scrollView in
List {
ForEach(messages.reversed(), id: \.id) { message in
MessageBubble(message: message,
isLastMessage: isLastMessage(message: message)
)
.flippedUpsideDown()
.listRowSeparator(.hidden)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 5, leading: 4, bottom: 5, trailing: 0))
.onAppear {
if message == messages.last && messageViewModel.hasMoreMessages && !messageViewModel.isLoadingMore && messageViewModel.initialLoadMessages{
loadMoreMessages()
}
// Send read receipt when the last message appears
if isLastMessage(message: message)
&& currentUserId != message.userId
&& !message.isRead
{
sendReadReceipt(for: message.messageId)
}
}
.anchorPreference(
key:BoundsPreference.self,
value: .bounds,
transform: { anchor in
return [message.id.uuidString : anchor]
})
.onLongPressGesture {
withAnimation(.easeInOut) {
selectedMessage = message
}
}
}
}
.listStyle(.plain)
.flippedUpsideDown()
.scrollContentBackground(.hidden)
.onChange(of: messages.count) { _ in
if let lastMessage = messages.last {
withAnimation {
scrollView.scrollTo(lastMessage.id, anchor: .bottom)
}
}
}
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
self.messageViewModel.initialLoadMessages = true
})
})
}
.regainSwipeBack()
.onTapGesture {
if isKeyboardVisible {
// Dismiss the keyboard when tapped outside of the TextField
hiddenKeyboard()
}
}
MessageInputBar(message: $newMessage,
isKeyboardVisible: $isKeyboardVisible,
alertType: $alertType,
webSocketManager: webSocketManager ) {
sendMessage()
}
}
.onAppear {
setupRoomMessagesListener()
}
.onDisappear {
removeRoomMessagesListener()
}
.frame(height: proxy.size.height)
}
.navigationBarBackButtonHidden()
.navigationBarTitleDisplayMode(.inline)
.toolbar(content: {
ToolbarItem(placement: .topBarLeading) {
Button(action: {
dismiss()
if !isNavigatedFromProfile {
TabBarModifier.showTabBar()
}
}) {
Image(systemName: "chevron.left")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 13)
.foregroundStyle(.black.opacity(0.7))
}
}
ToolbarItem(placement: .principal) {
HStack {
VStack(alignment: .center ,spacing: 2) {
Button {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
withAnimation {
isNavigatingToProfileView = true
}
})
} label: {
Text(webSocketManager.currentOnlineRecipient?.name ?? "User")
.bold()
}
.buttonStyle(.plain)
}
}
}
})
}
- Я пробовал много способов исправить проблему, включая удаление многих
компонентов, чтобы изолировать проблему. Я попытался поместить
MessageInputBar в .bottomBar панели инструментов, но проблема с пробелами
по-прежнему сохраняется.
Подробнее здесь: https://stackoverflow.com/questions/793 ... gation-how