BartoszCichecki BartoszCichecki - 1 year ago 102
iOS Question

Keyboard handling just like in Messages app in iOS 7

I am implementing a view that is in some way similar to what happens in Messages app, so there is a view with UITextView attached to the bottom of the screen and there is also UITableView showing the main content. When it is tapped it slides up with the keyboard and when keyboard is dismissed it slides back to the bottom of the screen.

That part I have and it is working perfectly - I just subscribed to keyboard notifications - will hide and wil show.

The problem is that I have set keyboard dismiss mode on UITableView to interactive and I cannot capture changes to keyboard when it is panning.

The second problem is that this bar with uitextview is covering some part of uitableview. How to fix this? I still want the uitableview to be "under" this bar just like in messages app.

I am using AutoLayout in all places.

Any help will be appreciated!


Here is some code:

View Hierarchy is as follows:

- UITableView (this one will contain "messages")
- UIView (this one will slide)

UITableView is has constraints to top, left, right and bottom of parent view so it fills whole screen.
UIView has constraints to left, right and bottom of parent view so it is glued to the bottom - I moved it by adjusting constant on constraint.

In ViewWillAppear method:

NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.DidShowNotification, OnKeyboardDidShowNotification);
NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillChangeFrameNotification, OnKeyboardDidShowNotification);
NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillHideNotification, OnKeyboardWillHideNotification);

And here are methods:

void OnKeyboardDidShowNotification (NSNotification notification)
AdjustViewToKeyboard (Ui.KeyboardHeightFromNotification (notification), notification);

void OnKeyboardWillHideNotification (NSNotification notification)
AdjustViewToKeyboard (0.0f, notification);

void AdjustViewToKeyboard (float offset, NSNotification notification = null)
commentEditViewBottomConstraint.Constant = -offset;

if (notification != null) {
UIView.BeginAnimations (null, IntPtr.Zero);
UIView.SetAnimationDuration (Ui.KeyboardAnimationDurationFromNotification (notification));
UIView.SetAnimationCurve ((UIViewAnimationCurve)Ui.KeyboardAnimationCurveFromNotification (notification));
UIView.SetAnimationBeginsFromCurrentState (true);

View.LayoutIfNeeded ();
commentEditView.LayoutIfNeeded ();

var insets = commentsListView.ContentInset;
insets.Bottom = offset;
commentsListView.ContentInset = insets;

if (notification != null) {
UIView.CommitAnimations ();

Answer Source

I made an open source lib for exactly this purpose. It works on iOS 7 and 8 and is set up to work as a cocoapod as well.

Here's a sample of what it looks like:


You can use a very basic init function as shown below to create it with screen width and default height e.g.:

self.messageComposerView = [[MessageComposerView alloc] init];
self.messageComposerView.delegate = self;
[self.view addSubview:self.messageComposerView];

There are several other initializers that are also available to allow you to customize the frame, keyboard offset and textview max height as well as some delegates to hook into frame changes and button clicks. See readme for more!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download