From 5f5db63df3dee3b2db5483bf95db000f99016d2a Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Tue, 24 Jan 2017 10:30:36 -0800 Subject: [PATCH] Handle double-height status bar on iOS (flutter/engine#3357) * Handle double-height status bar on iOS In certain cases, iOS displays a double-height status bar (e.g., when an application is using device location or while in a call). In such cases, iOS offsets the app view origin by 20px, reduces view height by 20px, then overlays a 40px opaque status bar: 20px covering the newly opened 20px gap at the top of the screen, 20px covering the top 20px of the view, which had previously been under the standard-sized status bar. Flutter previously set top padding to the height of the status bar, which resulted in 40px padding with a double-sized status bar. However, the padding should match the portion of the status bar overlapping the view, which is 20px. Note that the final case is the one in which no status bar is shown and padding should be zero. * Only apply status bar padding on root views --- .../framework/Source/FlutterViewController.mm | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 5b2b8b5d00..4cd0f49558 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -342,14 +342,22 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase( } - (void)viewDidLayoutSubviews { - CGSize size = self.view.bounds.size; + CGSize viewSize = self.view.bounds.size; + CGFloat statusBarPadding = 0.0; CGFloat scale = [UIScreen mainScreen].scale; + if (self.parentViewController == nil) { + // If we're the root view controller, apply any padding necessary for the + // status bar. If we're not the root view controller, assume the root view + // controller has dealt with it. + CGSize sbSize = [UIApplication sharedApplication].statusBarFrame.size; + statusBarPadding = sbSize.height - self.view.frame.origin.y; + } + _viewportMetrics.device_pixel_ratio = scale; - _viewportMetrics.physical_width = size.width * scale; - _viewportMetrics.physical_height = size.height * scale; - _viewportMetrics.physical_padding_top = - [UIApplication sharedApplication].statusBarFrame.size.height * scale; + _viewportMetrics.physical_width = viewSize.width * scale; + _viewportMetrics.physical_height = viewSize.height * scale; + _viewportMetrics.physical_padding_top = statusBarPadding * scale; [self updateViewportMetrics]; }