Reputation: 6199
First off. I know the SwiftUI ScrollView has limitations. I am hoping to get around that here.
My problem is I have a chat box...so a VStack with a ScrollView and a text input. I am able to get the text input to be keyboard adaptive...i.e. when you type it shifts up with the keyboard.
The issue is that the ScrollView loses its scroll position. So, if you scroll to the bottom and then activate the keyboard...you can't see the bottom anymore. It's almost like a ZStack.
What I want is to mimic the same behavior as WhatsApp which maintains scroll position while typing a new message.
I know about the ScrollViewReader and scrollTo...that seems to be a hack in this case and I'm hoping to avoid it. If anything, maybe there is a layout related fix?
Upvotes: 5
Views: 8326
Reputation: 494
Maybe a better option. If you are using iOS 14+ with scrollview or have the option to use scrollview.
https://developer.apple.com/documentation/swiftui/scrollviewproxy https://developer.apple.com/documentation/swiftui/scrollviewreader
Below might help
ScrollViewReader { (proxy: ScrollViewProxy) in
ScrollView {
view1().frame(height: 200)
view2().frame(height: 200)
view3() <-----this has textfields
.onTapGesture {
proxy.scrollTo(1, anchor: .center)
}
.id(1)
view4() <-----this has text editor
.onTapGesture {
proxy.scrollTo(2, anchor: .center)
}
.id(2)
view5().frame(height: 200)
view6().frame(height: 200)
submtButton().frame(height: 200)
}
}
imp part from above is
anyView().onTapGesture {
proxy.scrollTo(_ID, anchor: .center)
}.id(_ID)
Hope this helps someone :)
Upvotes: 2
Reputation: 6199
By a stroke of luck I was able to solve this by adding .keyboardAdaptive()
to both the ScrollView and the text input as well as changing from padding to offset
struct KeyboardAdaptive: ViewModifier {
@State private var keyboardHeight: CGFloat = 0
@State var offset: CGFloat
func body(content: Content) -> some View {
content
.offset(y: -keyboardHeight)
.onReceive(Publishers.keyboardHeight) {
self.keyboardHeight = $0 == 0 ? 0 : $0 - offset
}
}
}
Upvotes: 3