iOS: Compute screen available geometry based on safe area insets
In addition to the (deprecated) applicationFrame property, we base the available geometry on the root view's safe area, which also takes into account system-reserved areas on iPhone X, and the screen's bezel in the case of tvOS. Change-Id: I252d960a0e486dd0c7e30843f88c0bf5684feb24 Reviewed-by: Jake Petroules <jake.petroules@qt.io>bb10
parent
109290753b
commit
1a55c92933
|
|
@ -175,6 +175,21 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
|
|||
|
||||
@end
|
||||
|
||||
@interface UIScreen (Compatibility)
|
||||
@property (nonatomic, readonly) CGRect qt_applicationFrame;
|
||||
@end
|
||||
|
||||
@implementation UIScreen (Compatibility)
|
||||
- (CGRect)qt_applicationFrame
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
return self.applicationFrame;
|
||||
#else
|
||||
return self.bounds;
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -271,11 +286,15 @@ void QIOSScreen::updateProperties()
|
|||
QRect previousAvailableGeometry = m_availableGeometry;
|
||||
|
||||
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
|
||||
#ifdef Q_OS_TVOS
|
||||
m_availableGeometry = m_geometry;
|
||||
#else
|
||||
m_availableGeometry = QRectF::fromCGRect(m_uiScreen.applicationFrame).toRect();
|
||||
#endif
|
||||
|
||||
// The application frame doesn't take safe area insets into account, and
|
||||
// the safe area insets are not available before the UIWindow is shown,
|
||||
// and do not take split-view constraints into account, so we have to
|
||||
// combine the two to get the correct available geometry.
|
||||
QRect applicationFrame = QRectF::fromCGRect(m_uiScreen.qt_applicationFrame).toRect();
|
||||
UIEdgeInsets safeAreaInsets = m_uiWindow.qt_safeAreaInsets;
|
||||
m_availableGeometry = m_geometry.adjusted(safeAreaInsets.left, safeAreaInsets.top,
|
||||
-safeAreaInsets.right, -safeAreaInsets.bottom).intersected(applicationFrame);
|
||||
|
||||
#ifndef Q_OS_TVOS
|
||||
if (m_uiScreen == [UIScreen mainScreen]) {
|
||||
|
|
|
|||
|
|
@ -77,5 +77,6 @@ QT_END_NAMESPACE
|
|||
- (QWindow *)qwindow;
|
||||
- (UIViewController *)viewController;
|
||||
- (QIOSViewController*)qtViewController;
|
||||
@property (nonatomic, readonly) UIEdgeInsets qt_safeAreaInsets;
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -545,6 +545,22 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)qt_safeAreaInsets
|
||||
{
|
||||
#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA)
|
||||
if (__builtin_available(iOS 11, tvOS 11, *))
|
||||
return self.safeAreaInsets;
|
||||
#endif
|
||||
|
||||
// Fallback for iOS < 11
|
||||
UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
|
||||
CGPoint topInset = [self convertPoint:CGPointMake(0, self.viewController.topLayoutGuide.length) fromView:nil];
|
||||
CGPoint bottomInset = [self convertPoint:CGPointMake(0, self.viewController.bottomLayoutGuide.length) fromView:nil];
|
||||
safeAreaInsets.top = topInset.y;
|
||||
safeAreaInsets.bottom = bottomInset.y;
|
||||
return safeAreaInsets;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
|
|
|||
Loading…
Reference in New Issue