How do I show a message that appears above the keyboard, when the keyboard is already visible?
jmarr opened this issue · 5 comments
If I do config.keyboardTrackingView = KeyboardTrackingView()
, I can show a message and then make the keyboard visible, and the message slides up so that it remains above the keyboard (though I do see the issue mentioned in #496). However, once the keyboard is visible, if I show another message, it appears at the bottom of the view, behind the keyboard.
Next I tried creating and installing a KeyboardTrackingView
into my view controller's view hierarchy and setting that as the config.keyboardTrackingView
. Then if I show a message after the keyboard is up, the message appears above the keyboard. However, if I dismiss the keyboard, bring the keyboard back up, and then show another message, the message appears behind the keyboard.
Finally, I tried creating and installing a KeyboardTrackingView
into my view controller's view hierarchy and then creating another UIView
with its top anchored to the top of the viewController's view and its bottom anchored to the top of the KeyboardTrackingView
and then using that view for the presentationContext
. This generally seems to work (though it also suffered from the issue mentioned in #496). Would this be the recommended approach or should it work when using the config.keyboardTrackingView
?
I'm super busy, but I will do my best to take a look at this soon. It is a fairly obscure feature, so I wouldn't be surprised if it has some rough edges.
I took a look and found a couple of issues:
First, KeyboardTrackingView
is based on notifications. If you create a new one after the keyboard has already appeared, it won't know the current state of the keyboard. This was designed before keyboard layout margins existed :(
I have a slightly modified version of KeyboardTrackingView
that works if you hold onto it in your view controller and reuse the same instance with each message view. However, there is still a small issue related to safe area. All of the nib files provided with SwiftMessages rely on the layoutMargins
property to position the content. When you show a message, the appropriate layout margins are calculated based on the safe area. This can cause problems when combined with the keyboard tracking behavior:
- If the message is displayed before the keyboard appears, the bottom margin is too big after the keyboard pushes it up.
- If the message is displayed before the keyboard appears, the bottom margin is too small if the keyboard is dismissed, leaving the message view in the safe area.
Again, this stuff was designed before safe area existed :(
I'm not going to have time to rework the layout system for this particular issue. However, if you're willing to use your own view that internally constrains the content to bottom safe area, rather than one of the bundled nib files, I think my updated KeyboardTrackingView
will probably work for you.
Let me know what you think.
Awesome, thanks for looking into this. I saw you made some changes in 9.0.9, so I'll play around with that and creating our own view and let you know how it goes.
The idea with the updated KeyboardTrackingView
is that your view controller needs to create and hold onto a single instance and use that instance for each message. That way it retains the memory of the state of the keyboard. For the view, you need to set it up such that it uses Auto Layout to avoid the safe area rather than having SwiftMessages calculate the margins. I can help out with that if you get stuck.
Great! I've installed a KeyboardTrackingView
in my view controller and modified a copy of the CardView
nib to constrain the bottom of the corner rounding view to the bottom safe area (minus an 8pt margin) and that seems to be working well. Thanks so much!