diff options
author | Richard Moe Gustavsen <richard.gustavsen@digia.com> | 2014-02-25 14:16:23 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-21 08:41:23 +0100 |
commit | 37ba38b33457412ba55c37cc69dd618ef21bda5b (patch) | |
tree | 55884aa63b9c3d507e5f65cfb3a33fea338bc8fd | |
parent | 3d5234eb9a200752bce8fb2539efeb4d812b3b27 (diff) |
iOS: implement 'close keyboard' gesture
Before this patch there were no way for the user to hide
the keyboard on iPhone for multi-line edit fields unless
the app had a separate button added for it. And even that
would be problematic since we scroll the screen (and
perhaps the button) to track the cursor.
This patch implements a gesture that resembles the 'hide
keyboard' gesture that UIScrollView implements on iOS 7.
Note that if you start the gesture inside the edit field,
you will start selecting text as well. This will also cause
the cursor to move and the screen to scroll. After some
testing and failing, it seems like we need to live with such
artifacts until we do get around to do the only sensible thing;
fix up how we do text selection on touch platforms. Working
around it becomes just to messy.
Change-Id: I1c0d9c88ff1f5430587a49591f165b9708e5dc60
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
-rw-r--r-- | src/plugins/platforms/ios/qiosinputcontext.mm | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index fff7de8170..13a0b46745 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -39,13 +39,16 @@ ** ****************************************************************************/ -#include "qiosglobal.h" #include "qiosinputcontext.h" + +#import <UIKit/UIGestureRecognizerSubclass.h> + +#include "qiosglobal.h" #include "qioswindow.h" #include "quiview.h" #include <QGuiApplication> -@interface QIOSKeyboardListener : NSObject { +@interface QIOSKeyboardListener : UIGestureRecognizer { @public QIOSInputContext *m_context; BOOL m_keyboardVisible; @@ -63,7 +66,7 @@ - (id)initWithQIOSInputContext:(QIOSInputContext *)context { - self = [super init]; + self = [super initWithTarget:self action:@selector(gestureTriggered)]; if (self) { m_context = context; m_keyboardVisible = NO; @@ -82,6 +85,14 @@ } } Q_ASSERT(m_viewController); + + // Attach 'hide keyboard' gesture to the window, but keep it disabled when the + // keyboard is not visible. Note that we never trigger the gesture the way it is intended + // since we don't want to cancel touch events and interrupt flicking etc. Instead we use + // the gesture framework more as an event filter and hide the keyboard silently. + self.enabled = NO; + self.delaysTouchesEnded = NO; + [m_viewController.view.window addGestureRecognizer:self]; } [[NSNotificationCenter defaultCenter] @@ -102,7 +113,9 @@ - (void) dealloc { + [m_viewController.view.window removeGestureRecognizer:self]; [m_viewController release]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIKeyboardWillShowNotification" object:nil]; @@ -150,6 +163,7 @@ // Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked. m_keyboardVisibleAndDocked = YES; m_keyboardEndRect = [self getKeyboardRect:notification]; + self.enabled = YES; if (!m_duration) { m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16); @@ -164,6 +178,7 @@ // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked. m_keyboardVisibleAndDocked = NO; m_keyboardEndRect = [self getKeyboardRect:notification]; + self.enabled = NO; m_context->scroll(0); } @@ -183,6 +198,15 @@ } } +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + QPointF p = fromCGPoint([[touches anyObject] locationInView:m_viewController.view]); + if (m_keyboardRect.contains(p)) + m_context->hideInputPanel(); + + [super touchesMoved:touches withEvent:event]; +} + @end QIOSInputContext::QIOSInputContext() |