From 2ec20aaebe214714b8f9436d2bf6b6e1d1c8fb76 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Thu, 20 Sep 2018 18:28:05 -0700 Subject: [PATCH] Remove bottom safe-area padding when keyboard up (#6297) On the iPhone X, raising the keyboard sets a bottom physical inset equal to the keyboard height, however we previously did not zero out the bottom physical padding. This was incorrect; when a soft keyboard is present, it 'consumes' the safe area inset for the home indicator widget, eliminating the need for the app to handle this at all. --- .../framework/Source/FlutterViewController.mm | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index f90d2862eaf..993d7327a34 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -688,8 +688,8 @@ static inline blink::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* to - (CGFloat)statusBarPadding { UIScreen* screen = self.view.window.screen; CGRect statusFrame = [UIApplication sharedApplication].statusBarFrame; - CGRect viewFrame = - [self.view convertRect:self.view.bounds toCoordinateSpace:screen.coordinateSpace]; + CGRect viewFrame = [self.view convertRect:self.view.bounds + toCoordinateSpace:screen.coordinateSpace]; CGRect intersection = CGRectIntersection(statusFrame, viewFrame); return CGRectIsNull(intersection) ? 0.0 : intersection.size.height; } @@ -740,12 +740,25 @@ static inline blink::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* to NSDictionary* info = [notification userInfo]; CGFloat bottom = CGRectGetHeight([[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]); CGFloat scale = [UIScreen mainScreen].scale; + + // The keyboard is treated as an inset since we want to effectively reduce the window size by the + // keyboard height. We also eliminate any bottom safe-area padding since they keyboard 'consumes' + // the home indicator widget. _viewportMetrics.physical_view_inset_bottom = bottom * scale; + _viewportMetrics.physical_padding_bottom = 0; [self updateViewportMetrics]; } - (void)keyboardWillBeHidden:(NSNotification*)notification { + CGFloat scale = [UIScreen mainScreen].scale; _viewportMetrics.physical_view_inset_bottom = 0; + + // Restore any safe area padding that the keyboard had consumed. + if (@available(iOS 11, *)) { + _viewportMetrics.physical_padding_bottom = self.view.safeAreaInsets.bottom * scale; + } else { + _viewportMetrics.physical_padding_top = [self statusBarPadding] * scale; + } [self updateViewportMetrics]; } @@ -946,8 +959,9 @@ static inline blink::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* to // the "current system locale" or a custom one. On iOS it only applies to the current // system locale. Widget implementors must take this into account in order to provide // platform-idiomatic behavior in their widgets. - NSString* dateFormat = - [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]]; + NSString* dateFormat = [NSDateFormatter dateFormatFromTemplate:@"j" + options:0 + locale:[NSLocale currentLocale]]; return [dateFormat rangeOfString:@"a"].location == NSNotFound; } @@ -1075,8 +1089,8 @@ constexpr CGFloat kStandardStatusBarHeight = 20.0; - (NSObject*)registrarForPlugin:(NSString*)pluginKey { NSAssert(self.pluginPublications[pluginKey] == nil, @"Duplicate plugin key: %@", pluginKey); self.pluginPublications[pluginKey] = [NSNull null]; - return - [[FlutterViewControllerRegistrar alloc] initWithPlugin:pluginKey flutterViewController:self]; + return [[FlutterViewControllerRegistrar alloc] initWithPlugin:pluginKey + flutterViewController:self]; } - (BOOL)hasPlugin:(NSString*)pluginKey {