Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

View that moves along with keyboard

I have an iOS app with a UIScrollView that basically looks like the Messages.app: content on the screen and on the bottom a text view and a button to add more content. When the keyboard appears the text view and button move up correctly.

I've set keyboardDismissMode so that dragging the keyboard down makes it disappear but during the process of the dragging, as the keyboard is moving down, how can I update my views' locations on screen to stay attached to it? It seems that the keyboard will change frame notification isn't fired during this process.

What's the "right" way of doing this?

Edit: I have a hunch it might be doable using an input view/accessory view, but not sure that's the right direction to go.

like image 889
abyx Avatar asked Nov 11 '22 19:11

abyx


1 Answers

Pretty sure this behavior requires SPI. BUT: You could walk the view/window hierarchy, find the keyboard window, and apply a transform to it to move it during your interaction. (window.transform=)

Not sure what to do when your interaction ends however--maybe manually animate the keyboard away (using the above technique) to finish the keyboard hide, then when it's hidden, resign first responder without animating.

EDIT:

Sorry, I thought you wanted to move the keyboard, but if you want to observe the keyboards position, you can use KVO for that (as @KudoCC suggested)

static void * __keyboardCenterKVOContext = & __keyboardCenterKVOContext ;

-(void)setUpKeyboardObserver
{
    UIView * keyboardView = ...?
    [ keyboardView addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:__keyboardCenterKVOContext ] ;
}

Then implement the KVO observer:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ( context == __keyboardCenterKVOContext )
    {
        CGPoint newKeyboardCenter = [ [ change valueForKey:NSKeyValueChangeNewKey ] pointValue ] ;
        // .. handle new keyboard position here ...
    }
    else
    {
        [ super observeValueForKeyPath:keyPath ofObject:object change:change context:context ] ;
    }
}

Your KVO observer will be run every time the keyboard view changes it's center property. You might also try observing the keyboard window's frame and/or transform properties.

I have some code to help with KVO observing here, which might help you: https://gist.github.com/nielsbot/6873377

(The reason you might want to use my helper code is because it automatically removes KVO observation from objects that are being deallocated. This requires some run time fiddling, but in your case you don't really know when the keyboard window will be deallocated. Although maybe you can tear down KVO in your keyboardWillHide handler)

like image 79
nielsbot Avatar answered Nov 15 '22 06:11

nielsbot