Fix iPhoneX layout show status bar above call banner

// FREEBIE
This commit is contained in:
Michael Kirk 2018-05-18 09:12:01 -04:00 committed by Matthew Chen
parent 3383c5e80c
commit 4c9808d1a1
6 changed files with 59 additions and 9 deletions

View File

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

View File

@ -49,11 +49,17 @@ NS_ASSUME_NONNULL_BEGIN
if (@available(iOS 11.0, *)) {
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 {
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];
} else {
// Pre iOS11 we size the navbar, and position it vertically once.

View File

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

View File

@ -16,9 +16,12 @@ NSString *const OWSWindowManagerCallDidChangeNotification = @"OWSWindowManagerCa
const CGFloat OWSWindowManagerCallScreenHeight(void)
{
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;
} 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
// 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
// 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)
{
return UIWindowLevelStatusBar + 1.f;
return UIWindowLevelStatusBar - 1;
}
// In front of the root window, behind the screen blocking window.
@ -122,15 +124,34 @@ const UIWindowLevel UIWindowLevel_ScreenBlocking(void)
OWSAssert(screenBlockingWindow);
OWSAssert(!self.screenBlockingWindow);
// MJK FIXME
rootWindow.backgroundColor = UIColor.yellowColor;
self.rootWindow = rootWindow;
self.screenBlockingWindow = screenBlockingWindow;
self.returnToCallWindow = [self createReturnToCallWindow:rootWindow];
self.callViewWindow = [self createCallViewWindow:rootWindow];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didChangeStatusBarFrame:)
name:UIApplicationDidChangeStatusBarFrameNotification
object:nil];
[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
{
OWSAssertIsOnMainThread();

View File

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

View File

@ -135,6 +135,12 @@ NS_ASSUME_NONNULL_BEGIN
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
{
return self.isSAEInBackground;