summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-07-29 19:02:11 +0200
committerTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-09-24 11:52:28 +0200
commitd61d6387215003bbccf519f7f5e16011b9014d13 (patch)
tree7a417f8f8d9c9db447c412115f8e655a00f50453
parent6742b250b5d670cb91d1d523d6f0bd931a9442b3 (diff)
iOS: Scroll root view when keyboard is visible using sublayerTransform
We opt to use sublayerTransform instead of changing the root view's bounds, so that we can keep the root view at the same position and size regardless of statusbar height and visibility. Change-Id: I3f04a4587f1108084208aefa990f91a130fb47b8 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index aeef24b0b3..c42ea6437b 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -370,18 +370,39 @@ void QIOSInputContext::scrollToCursor()
void QIOSInputContext::scroll(int y)
{
- // Scroll the view the same way a UIScrollView
- // works: by changing bounds.origin:
- UIView *view = m_keyboardListener->m_viewController.view;
- if (y == view.bounds.origin.y)
+ UIView *rootView = m_keyboardListener->m_viewController.view;
+
+ CATransform3D translationTransform = CATransform3DMakeTranslation(0.0, -y, 0.0);
+ if (CATransform3DEqualToTransform(translationTransform, rootView.layer.sublayerTransform))
return;
- CGRect newBounds = view.bounds;
- newBounds.origin.y = y;
QPointer<QIOSInputContext> self = this;
[UIView animateWithDuration:m_keyboardListener->m_duration delay:0
options:(m_keyboardListener->m_curve << 16) | UIViewAnimationOptionBeginFromCurrentState
- animations:^{ view.bounds = newBounds; }
+ animations:^{
+ // The sublayerTransform property of CALayer is not implicitly animated for a
+ // layer-backed view, even inside a UIView animation block, so we need to set up
+ // an explicit CoreAnimation animation. Since there is no predefined media timing
+ // function that matches the custom keyboard animation curve we cheat by asking
+ // the view for an animation of another property, which will give us an animation
+ // that matches the parameters we passed to [UIView animateWithDuration] above.
+ // The reason we ask for the animation of 'backgroundColor' is that it's a simple
+ // property that will not return a compound animation, like eg. bounds will.
+ NSObject *action = (NSObject*)[rootView actionForLayer:rootView.layer forKey:@"backgroundColor"];
+
+ CABasicAnimation *animation;
+ if ([action isKindOfClass:[CABasicAnimation class]]) {
+ animation = static_cast<CABasicAnimation*>(action);
+ animation.keyPath = @"sublayerTransform"; // Instead of backgroundColor
+ } else {
+ animation = [CABasicAnimation animationWithKeyPath:@"sublayerTransform"];
+ }
+
+ animation.fromValue = [NSValue valueWithCATransform3D:rootView.layer.sublayerTransform];
+ animation.toValue = [NSValue valueWithCATransform3D:translationTransform];
+ [rootView.layer addAnimation:animation forKey:@"AnimateSubLayerTransform"];
+ rootView.layer.sublayerTransform = translationTransform;
+ }
completion:^(BOOL){
if (self)
[m_keyboardListener handleKeyboardRectChanged];