Closed nucleartux closed 2 years ago
I think you should not use AvoidSoftInputView
, could you try setEnable(true)
when the screen is active & setEanble(false)
when it's not ?
I deleted AvoidSoftInputView
and added this code:
const onFocusEffect = useCallback(() => {
AvoidSoftInput.setEnabled(true);
return () => {
AvoidSoftInput.setEnabled(false);
};
}, []);
useFocusEffect(onFocusEffect);
Now it completely hides navigation header. How I can fix that?
https://user-images.githubusercontent.com/199706/161310942-b250944a-9027-4b43-b47a-39382e8f8b9a.mp4
And anyway bug still present. Even if I try to disable on transition start:
useEffect(() => {
const unsubscribe = navigation.addListener("transitionStart", () => {
AvoidSoftInput.setEnabled(false);
});
return unsubscribe;
}, [navigation]);
Hi @nucleartux
And I have related question: now, when I swipe screen keyboard still present but keyboard avoid view smoothly disappears (and content scrolls down). How I can prevent this behavior?
That's default iOS behavior, keyboard is still fully visible, even though app receives events from UIResponder.keyboardWillChangeFrameNotification
:
I don't know if it can be prevented, you can try with writing your own logic for applying padding to your container based on useSoftInputShown
& useSoftInputHidden
hooks, but I don't guarantee, that it will make a satisfying result.
@nucleartux issue is fixed and available in version 2.4.2 🎉
@mateusz1913 hello I updated library and added screenOptions. Now screen (avoid soft input part) moves together with keyboard but still breaks on swipe cancel. So it's expected behaviour, right?
https://user-images.githubusercontent.com/199706/161418102-c1b9b20a-7536-409a-8383-a60f0fd5ab94.mov
On the provided video, after you cancel swipe, can you scroll to the very bottom (so the input and all messages are visible as it was before the swipe)?
If not, please create reproduction repo and link it in issue's description, so I will be able to investigate and reopen this issue
It's not possible.
https://user-images.githubusercontent.com/199706/161418853-aa17d141-9230-4f56-9806-4e8e8c9e4716.mov
I will try to make repro demo.
I'm in process of repro but found another bug(?). Can you help me investigate it? https://github.com/nucleartux/TestProject
https://user-images.githubusercontent.com/199706/161420146-a12c1bed-4efe-4b3a-9c73-9053dfcb6603.mp4
Ok I get it. If you add avoidOffset={16}
to my demo it will collapse keyboard after swipe cancel.
Without avoidOffset
it adds height every time swipe canceled.
So maybe it's two separate bugs, i'm not sure.
I downloaded your repo and can't reproduce behavior from video
I added nice Swift package ShowTime, so you will see where I make touches
How it is even possible? I tried delete node_modules and pods and reinstall everything again but bug still exists.
Which simulator, do you use?
Simulator. iPhone 13, iOS 15.4
Weird. I will try on real device
I tried on real device (iPhone X, latest iOS) - same bug.
Ok, I reproduced on real device. Will investigate it and probably create separate ticket.
In the meantime, please prepare that chat repro and I will reopen this ticket
I will track second one here: https://github.com/mateusz1913/react-native-avoid-softinput/issues/59
I made separate branch for this issue https://github.com/nucleartux/TestProject/tree/issue-54
https://user-images.githubusercontent.com/199706/161431126-a6ced7ce-8e27-434b-a37d-5252dba4ad9f.mp4
@nucleartux Can you try following patch?
diff --git a/node_modules/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift b/node_modules/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
index 3f30b5a..685dd3f 100644
--- a/node_modules/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
+++ b/node_modules/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
@@ -34,6 +34,8 @@ class AvoidSoftInputManager: NSObject {
private var showDelay: Double = SHOW_ANIMATION_DELAY_IN_SECONDS
private var showDuration: Double = SHOW_ANIMATION_DURATION_IN_SECONDS
private var softInputVisible: Bool = false
+ private var wasAddOffsetInRootViewAborted = false
+ private var wasAddOffsetInScrollViewAborted = false
func setAvoidOffset(_ offset: NSNumber) {
avoidOffset = CGFloat(offset.floatValue)
@@ -157,7 +159,7 @@ class AvoidSoftInputManager: NSObject {
private func decreaseOffsetInRootView(from: CGFloat, to: CGFloat, rootView: UIView) {
let addedOffset = to - from
- let newBottomOffset = isShowAnimationRunning ? bottomOffset : bottomOffset + addedOffset
+ let newBottomOffset = isShowAnimationRunning || wasAddOffsetInRootViewAborted ? bottomOffset : bottomOffset + addedOffset
if newBottomOffset < 0 {
return
@@ -175,7 +177,7 @@ class AvoidSoftInputManager: NSObject {
private func increaseOffsetInRootView(from: CGFloat, to: CGFloat, rootView: UIView) {
let addedOffset = to - from
- let newBottomOffset = isHideAnimationRunning ? bottomOffset : bottomOffset + addedOffset
+ let newBottomOffset = isHideAnimationRunning || wasAddOffsetInRootViewAborted ? bottomOffset : bottomOffset + addedOffset
if newBottomOffset < 0 {
return
@@ -211,6 +213,7 @@ class AvoidSoftInputManager: NSObject {
private func addOffsetInRootView(_ offset: CGFloat, firstResponder: UIView, rootView: UIView) {
guard let firstResponderPosition = firstResponder.superview?.convert(firstResponder.frame.origin, to: nil) else {
+ wasAddOffsetInRootViewAborted = true
return
}
@@ -221,13 +224,15 @@ class AvoidSoftInputManager: NSObject {
let firstResponderDistanceToBottom = UIScreen.main.bounds.size.height - (firstResponderPosition.y + firstResponder.frame.height) - bottomSafeInset
- let newOffset = max(offset - firstResponderDistanceToBottom, 0) + avoidOffset
+ let newOffset = max(offset - firstResponderDistanceToBottom, 0)
if (newOffset <= 0) {
+ wasAddOffsetInRootViewAborted = true
return
}
- bottomOffset = newOffset
+ wasAddOffsetInRootViewAborted = false
+ bottomOffset = newOffset + avoidOffset
beginShowAnimation(initialOffset: 0, addedOffset: bottomOffset)
UIView.animate(withDuration: showDuration, delay: showDelay, options: [.beginFromCurrentState, easingOption]) {
@@ -265,7 +270,7 @@ class AvoidSoftInputManager: NSObject {
private func decreaseOffsetInScrollView(from: CGFloat, to: CGFloat, firstResponder: UIView, scrollView: UIScrollView, rootView: UIView) {
let addedOffset = to - from
- let newBottomOffset = isShowAnimationRunning ? bottomOffset : bottomOffset + addedOffset
+ let newBottomOffset = isShowAnimationRunning || wasAddOffsetInScrollViewAborted ? bottomOffset : bottomOffset + addedOffset
let scrollToOffset = getScrollToOffset(softInputHeight: to, firstResponder: firstResponder, scrollView: scrollView, rootView: rootView)
if newBottomOffset < 0 {
@@ -291,7 +296,7 @@ class AvoidSoftInputManager: NSObject {
private func increaseOffsetInScrollView(from: CGFloat, to: CGFloat, firstResponder: UIView, scrollView: UIScrollView, rootView: UIView) {
let addedOffset = to - from
- let newBottomOffset = isHideAnimationRunning ? bottomOffset : bottomOffset + addedOffset
+ let newBottomOffset = isHideAnimationRunning || wasAddOffsetInScrollViewAborted ? bottomOffset : bottomOffset + addedOffset
let scrollToOffset = getScrollToOffset(softInputHeight: to, firstResponder: firstResponder, scrollView: scrollView, rootView: rootView)
if newBottomOffset < 0 {
@@ -344,6 +349,7 @@ class AvoidSoftInputManager: NSObject {
}
guard let scrollViewPosition = scrollView.superview?.convert(scrollView.frame.origin, to: nil) else {
+ wasAddOffsetInScrollViewAborted = true
return
}
@@ -351,13 +357,15 @@ class AvoidSoftInputManager: NSObject {
let scrollToOffset = getScrollToOffset(softInputHeight: offset, firstResponder: firstResponder, scrollView: scrollView, rootView: rootView)
- let newOffset = max(offset - scrollViewDistanceToBottom, 0) + avoidOffset
+ let newOffset = max(offset - scrollViewDistanceToBottom, 0)
if newOffset <= 0 {
+ wasAddOffsetInScrollViewAborted = true
return
}
- bottomOffset = newOffset
+ wasAddOffsetInScrollViewAborted = false
+ bottomOffset = newOffset + avoidOffset
if !softInputVisible {
// Save original scroll insets
I think it should resolve both issues
Tested on repro and real project, works fine! You saved my life 🕺
But one question. It works fine with fullScreenGestureEnabled
enabled but without it on swipe flat list goes under keyboard (video in very first post). Can I somehow workaround it and with disabled fullScreenGestureEnabled
?
It's just question, issue is solved anyway.
I'll check that, probably it shouldn't work like that
Ah, ok, I misunderstood your question. So I guess that fullScreenGestureEnabled
option is making keyboard interactive when dismissing it
Fix is available in v2.4.3
Environment
Library version: 2.4.1 OS version: iPhone 13, iOS 15.4 "@react-navigation/native": "^6.0.8", "@react-navigation/native-stack": "^6.6.1",
Affected platforms
Current behavior
https://user-images.githubusercontent.com/199706/161307457-5d118360-c530-479a-b52e-c69cd62ef98b.mp4
Expected behavior
Keyboard avoid view
Reproduction
const styles = StyleSheet.create({ container: { flex: 1, }, ... })