I need that when keyboard appears it will push scrollView (Message bubbles or messages) up too. It pushes textfield only. Which approach is good? And also how to make that when MessageView appears scrollView starts from bottom, not from top as default?
import SwiftUI
import Combine
import CoreData
var body: some View {
ZStack {
ScrollViewReader { scrollView in
ScrollView(showsIndicators: false) {
LazyVStack(spacing: 4) {
ForEach(messagesViewModel.messages.indices, id: \.self) { index in
let isLastMessage = index == messagesViewModel.messages.indices.last
MessageBubble(message: messagesViewModel.messages[index],
isLastMessage: isLastMessage,
isLastBeforeDirectionChange: false,
swipeOffset: $swipeOffset)
}
}
.padding(.bottom, 50)
.gesture(
DragGesture()
.onChanged { value in
if !isVerticalDragInProgress && abs(value.translation.width) > abs(value.translation.height) {
withAnimation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0)) {
swipeOffset = min(0, max(value.translation.width, -60))
}
}
}
.onEnded { _ in
if !isVerticalDragInProgress {
withAnimation(.spring()) {
swipeOffset = 0
}
}
}
)
}
.padding(.horizontal, 7)
.scrollDismissesKeyboard(.interactively)
}
VStack {
Spacer()
HStack {
TextField("New Message", text: $newMessage, axis: .vertical)
.autocorrectionDisabled()
.padding(.horizontal)
.padding(5)
.background(background)
.clipShape(RoundedRectangle(cornerRadius: 30))
.overlay(
RoundedRectangle(cornerRadius: 30)
.stroke(gradient, lineWidth: 1.3)
)
if newMessage.isEmpty {
Button(action: {
if isMicButton {
// Send Audio Message
} else {
// Send Video Message
}
withAnimation(Animation.bouncy(duration: 0.1, extraBounce: 0.3)) {
isMicButton.toggle()
}
}) {
Image(systemName: isMicButton ? "mic.fill" : "video.fill")
.font(.system(size: 25))
.foregroundColor(colorScheme == .dark ? Color(hex: "#fffcf2").opacity(0.5) : Color(hex: "#415675"))
}
} else {
Button(action: {
messagesViewModel.sendMessage(text: newMessage)
newMessage = ""
}) {
Image(systemName: "paperplane.fill")
.font(.system(size: 25))
.foregroundColor(colorScheme == .dark ? Color(hex: "#fffcf2").opacity(0.5) : Color(hex: "#415675"))
}
}
}
.padding(.horizontal)
.padding(7)
.background(.ultraThinMaterial)
}
}
.edgesIgnoringSafeArea(.horizontal)
.navigationBarTitle(contactName, displayMode: .inline)
}
}
I tried to wrap scrollview and HStack into the VStack, not working. Should I use SafeArea? And how?