Fix iPhoneX layout show status bar above call banner

// FREEBIE
pull/1/head
Michael Kirk 7 years ago committed by Matthew Chen
parent 3383c5e80c
commit 4c9808d1a1

@ -128,6 +128,11 @@ NS_ASSUME_NONNULL_BEGIN
[[UIApplication sharedApplication] setStatusBarHidden:isHidden animated:isAnimated]; [[UIApplication sharedApplication] setStatusBarHidden:isHidden animated:isAnimated];
} }
- (CGFloat)statusBarHeight
{
return [UIApplication sharedApplication].statusBarFrame.size.height;
}
- (BOOL)isInBackground - (BOOL)isInBackground
{ {
return [UIApplication sharedApplication].applicationState == UIApplicationStateBackground; return [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;

@ -49,11 +49,17 @@ NS_ASSUME_NONNULL_BEGIN
if (@available(iOS 11.0, *)) { if (@available(iOS 11.0, *)) {
if (OWSWindowManager.sharedManager.hasCall) { if (OWSWindowManager.sharedManager.hasCall) {
self.additionalSafeAreaInsets = UIEdgeInsetsMake(64, 0, 0, 0); if (UIDevice.currentDevice.isIPhoneX) {
// iPhoneX computes status bar height differently.
self.additionalSafeAreaInsets = UIEdgeInsetsMake(navbar.navbarWithoutStatusHeight + 20, 0, 0, 0);
} else {
self.additionalSafeAreaInsets
= UIEdgeInsetsMake(navbar.navbarWithoutStatusHeight + CurrentAppContext().statusBarHeight, 0, 0, 0);
}
} else { } else {
self.additionalSafeAreaInsets = UIEdgeInsetsZero; self.additionalSafeAreaInsets = UIEdgeInsetsZero;
} }
// in iOS11 we have to ensure the position *in* layoutSubviews. // in iOS11 we have to ensure the navbar frame *in* layoutSubviews.
[navbar layoutSubviews]; [navbar layoutSubviews];
} else { } else {
// Pre iOS11 we size the navbar, and position it vertically once. // Pre iOS11 we size the navbar, and position it vertically once.

@ -16,22 +16,30 @@ class OWSNavigationBar: UINavigationBar {
weak var navBarLayoutDelegate: NavBarLayoutDelegate? weak var navBarLayoutDelegate: NavBarLayoutDelegate?
let navbarWithoutStatusHeight: CGFloat = 44 let navbarWithoutStatusHeight: CGFloat = 44
let callBannerHeight: CGFloat = OWSWindowManagerCallScreenHeight()
var callBannerHeight: CGFloat {
return OWSWindowManagerCallScreenHeight()
}
var statusBarHeight: CGFloat { var statusBarHeight: CGFloat {
return 20 return CurrentAppContext().statusBarHeight
} }
var fullWidth: CGFloat { var fullWidth: CGFloat {
return UIScreen.main.bounds.size.width return UIScreen.main.bounds.size.width
} }
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.isTranslucent = false self.isTranslucent = false
NotificationCenter.default.addObserver(self, selector: #selector(callDidChange), name: .OWSWindowManagerCallDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(callDidChange), name: .OWSWindowManagerCallDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didChangeStatusBarFrame), name: .UIApplicationDidChangeStatusBarFrame, object: nil)
} }
@objc @objc
@ -40,8 +48,10 @@ class OWSNavigationBar: UINavigationBar {
self.navBarLayoutDelegate?.navBarCallLayoutDidChange(navbar: self) self.navBarLayoutDelegate?.navBarCallLayoutDidChange(navbar: self)
} }
required init?(coder aDecoder: NSCoder) { @objc
fatalError("init(coder:) has not been implemented") public func didChangeStatusBarFrame() {
Logger.debug("\(self.logTag) in \(#function)")
self.navBarLayoutDelegate?.navBarCallLayoutDidChange(navbar: self)
} }
override func sizeThatFits(_ size: CGSize) -> CGSize { override func sizeThatFits(_ size: CGSize) -> CGSize {

@ -16,9 +16,12 @@ NSString *const OWSWindowManagerCallDidChangeNotification = @"OWSWindowManagerCa
const CGFloat OWSWindowManagerCallScreenHeight(void) const CGFloat OWSWindowManagerCallScreenHeight(void)
{ {
if ([UIDevice currentDevice].isIPhoneX) { if ([UIDevice currentDevice].isIPhoneX) {
// On an iPhoneX, the system return-to-call banner has been replaced by a much subtler green
// circle behind the system clock. Instead, we mimic the old system call banner as on older devices,
// but it has to be taller to fit beneath the notch.
return 64; return 64;
} else { } else {
return 40; return CurrentAppContext().statusBarHeight + 20;
} }
} }
@ -29,11 +32,10 @@ const UIWindowLevel UIWindowLevel_Background = -1.f;
// It obscures status bar content like the system clock // It obscures status bar content like the system clock
// But being behind the status bar introduces two worse problems that'd we'd need to address // But being behind the status bar introduces two worse problems that'd we'd need to address
// 1. Tap target is too small, only the 20px below the status bar are tappable // 1. Tap target is too small, only the 20px below the status bar are tappable
// 2. hot-spot connected banner obscure our return-to-call banner, so the user can't see that they're in a call.
const UIWindowLevel UIWindowLevel_ReturnToCall(void); const UIWindowLevel UIWindowLevel_ReturnToCall(void);
const UIWindowLevel UIWindowLevel_ReturnToCall(void) const UIWindowLevel UIWindowLevel_ReturnToCall(void)
{ {
return UIWindowLevelStatusBar + 1.f; return UIWindowLevelStatusBar - 1;
} }
// In front of the root window, behind the screen blocking window. // In front of the root window, behind the screen blocking window.
@ -122,15 +124,34 @@ const UIWindowLevel UIWindowLevel_ScreenBlocking(void)
OWSAssert(screenBlockingWindow); OWSAssert(screenBlockingWindow);
OWSAssert(!self.screenBlockingWindow); OWSAssert(!self.screenBlockingWindow);
// MJK FIXME
rootWindow.backgroundColor = UIColor.yellowColor;
self.rootWindow = rootWindow; self.rootWindow = rootWindow;
self.screenBlockingWindow = screenBlockingWindow; self.screenBlockingWindow = screenBlockingWindow;
self.returnToCallWindow = [self createReturnToCallWindow:rootWindow]; self.returnToCallWindow = [self createReturnToCallWindow:rootWindow];
self.callViewWindow = [self createCallViewWindow:rootWindow]; self.callViewWindow = [self createCallViewWindow:rootWindow];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didChangeStatusBarFrame:)
name:UIApplicationDidChangeStatusBarFrameNotification
object:nil];
[self ensureWindowState]; [self ensureWindowState];
} }
- (void)didChangeStatusBarFrame:(NSNotification *)notification
{
CGRect newFrame = self.returnToCallWindow.frame;
newFrame.size.height = OWSWindowManagerCallScreenHeight();
DDLogDebug(@"%@ StatusBar changed frames - updating returnToCallWindowFrame: %@",
self.logTag,
NSStringFromCGRect(newFrame));
self.returnToCallWindow.frame = newFrame;
}
- (UIWindow *)createReturnToCallWindow:(UIWindow *)rootWindow - (UIWindow *)createReturnToCallWindow:(UIWindow *)rootWindow
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();

@ -59,6 +59,8 @@ NSString *NSStringForUIApplicationState(UIApplicationState value);
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle; - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle;
- (void)setStatusBarHidden:(BOOL)isHidden animated:(BOOL)isAnimated; - (void)setStatusBarHidden:(BOOL)isHidden animated:(BOOL)isAnimated;
@property (nonatomic, readonly) CGFloat statusBarHeight;
// Returns the VC that should be used to present alerts, modals, etc. // Returns the VC that should be used to present alerts, modals, etc.
- (nullable UIViewController *)frontmostViewController; - (nullable UIViewController *)frontmostViewController;

@ -135,6 +135,12 @@ NS_ASSUME_NONNULL_BEGIN
DDLogInfo(@"Ignoring request to show/hide status bar style since we're in an app extension"); DDLogInfo(@"Ignoring request to show/hide status bar style since we're in an app extension");
} }
- (CGFloat)statusBarHeight
{
OWSFail(@"%@ in %s unexpected for share extension", self.logTag, __PRETTY_FUNCTION__);
return 20;
}
- (BOOL)isInBackground - (BOOL)isInBackground
{ {
return self.isSAEInBackground; return self.isSAEInBackground;

Loading…
Cancel
Save