From 9339f03ecd2fa2db404a594947d8adaaf16c5ff5 Mon Sep 17 00:00:00 2001 From: Markus Emrich Date: Wed, 11 Oct 2023 21:40:19 +0200 Subject: [PATCH] Base layout on safeAreaInset instead of deprecated statusBarFrame's Fixes #122 Fixes #130 --- .../project.pbxproj | 14 ------- .../Private/JDSBNotificationView.m | 14 ++----- .../Private/JDSBNotificationViewController.h | 2 +- .../Private/JDSBNotificationViewController.m | 2 +- .../Private/JDSBNotificationWindow.m | 37 +++++++------------ .../Private/JDSystemStatusBarHelpers.h | 8 ---- .../Private/JDSystemStatusBarHelpers.m | 25 ------------- 7 files changed, 19 insertions(+), 83 deletions(-) delete mode 100644 JDStatusBarNotification/Private/JDSystemStatusBarHelpers.h delete mode 100644 JDStatusBarNotification/Private/JDSystemStatusBarHelpers.m diff --git a/ExampleProject/JDStatusBarNotificationExample.xcodeproj/project.pbxproj b/ExampleProject/JDStatusBarNotificationExample.xcodeproj/project.pbxproj index 5a9ff6e5..60ff6179 100644 --- a/ExampleProject/JDStatusBarNotificationExample.xcodeproj/project.pbxproj +++ b/ExampleProject/JDStatusBarNotificationExample.xcodeproj/project.pbxproj @@ -38,8 +38,6 @@ 7E5402DD286708E70079C579 /* JDSBNotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EBE340F2844CA2D0096CD55 /* JDSBNotificationViewController.m */; }; 7E5402DE286708E70079C579 /* JDSBNotificationWindow.h in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140902847557600593D6F /* JDSBNotificationWindow.h */; }; 7E5402DF286708E70079C579 /* JDSBNotificationWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140912847557600593D6F /* JDSBNotificationWindow.m */; }; - 7E5402E0286708E70079C579 /* JDSystemStatusBarHelpers.h in Sources */ = {isa = PBXBuildFile; fileRef = 7EE516D6284711C900685DDF /* JDSystemStatusBarHelpers.h */; }; - 7E5402E1286708E70079C579 /* JDSystemStatusBarHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */; }; 7E5402E2286708E70079C579 /* UIApplication+JDSB_MainWindow.h in Sources */ = {isa = PBXBuildFile; fileRef = 7EBE34112844CA2D0096CD55 /* UIApplication+JDSB_MainWindow.h */; }; 7E5402E3286708E70079C579 /* UIApplication+JDSB_MainWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EBE340D2844CA2D0096CD55 /* UIApplication+JDSB_MainWindow.m */; }; 7E5402E5286709560079C579 /* JDStatusBarNotificationPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8C519428585BE400C7C003 /* JDStatusBarNotificationPresenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -63,7 +61,6 @@ 7E8C51A02858857200C7C003 /* TextStyleEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8C519F2858857200C7C003 /* TextStyleEditorView.swift */; }; 7E8C51A12858857200C7C003 /* TextStyleEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8C519F2858857200C7C003 /* TextStyleEditorView.swift */; }; 7E8C51A22858857200C7C003 /* TextStyleEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8C519F2858857200C7C003 /* TextStyleEditorView.swift */; }; - 7EA91CAA284EF3AF00F32F09 /* JDSystemStatusBarHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */; }; 7EA91CAB284EF3AF00F32F09 /* JDSBNotificationWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140912847557600593D6F /* JDSBNotificationWindow.m */; }; 7EA91CAD284EF3AF00F32F09 /* JDSBNotificationView.m in Sources */ = {isa = PBXBuildFile; fileRef = D25B0FA4184F343600B8174B /* JDSBNotificationView.m */; }; 7EA91CAF284EF3AF00F32F09 /* JDSBNotificationStyleCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140962848513800593D6F /* JDSBNotificationStyleCache.m */; }; @@ -86,8 +83,6 @@ 7ED140932847557600593D6F /* JDSBNotificationWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140912847557600593D6F /* JDSBNotificationWindow.m */; }; 7ED140972848513800593D6F /* JDSBNotificationStyleCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140962848513800593D6F /* JDSBNotificationStyleCache.m */; }; 7ED140982848513800593D6F /* JDSBNotificationStyleCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ED140962848513800593D6F /* JDSBNotificationStyleCache.m */; }; - 7EE516D7284711C900685DDF /* JDSystemStatusBarHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */; }; - 7EE516D8284711C900685DDF /* JDSystemStatusBarHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */; }; 7EEDBE142856EDD9007747AA /* StatusBarPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EEDBE132856EDD9007747AA /* StatusBarPreviewView.swift */; }; 7EEDBE152856EDD9007747AA /* StatusBarPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EEDBE132856EDD9007747AA /* StatusBarPreviewView.swift */; }; 7EEDBE162856EDD9007747AA /* StatusBarPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EEDBE132856EDD9007747AA /* StatusBarPreviewView.swift */; }; @@ -142,8 +137,6 @@ 7ED140912847557600593D6F /* JDSBNotificationWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JDSBNotificationWindow.m; sourceTree = ""; }; 7ED140952848513800593D6F /* JDSBNotificationStyleCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JDSBNotificationStyleCache.h; sourceTree = ""; }; 7ED140962848513800593D6F /* JDSBNotificationStyleCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JDSBNotificationStyleCache.m; sourceTree = ""; }; - 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JDSystemStatusBarHelpers.m; sourceTree = ""; }; - 7EE516D6284711C900685DDF /* JDSystemStatusBarHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JDSystemStatusBarHelpers.h; sourceTree = ""; }; 7EEDBE132856EDD9007747AA /* StatusBarPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarPreviewView.swift; sourceTree = ""; }; 7EFD77A12843461D000BFBF1 /* JDSBN_WindowSceneExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JDSBN_WindowSceneExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7EFD77A32843462F000BFBF1 /* WindowScene-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WindowScene-Info.plist"; sourceTree = ""; }; @@ -258,8 +251,6 @@ 7EBE340F2844CA2D0096CD55 /* JDSBNotificationViewController.m */, 7ED140902847557600593D6F /* JDSBNotificationWindow.h */, 7ED140912847557600593D6F /* JDSBNotificationWindow.m */, - 7EE516D6284711C900685DDF /* JDSystemStatusBarHelpers.h */, - 7EE516D5284711C900685DDF /* JDSystemStatusBarHelpers.m */, 7EBE34112844CA2D0096CD55 /* UIApplication+JDSB_MainWindow.h */, 7EBE340D2844CA2D0096CD55 /* UIApplication+JDSB_MainWindow.m */, ); @@ -528,8 +519,6 @@ 7E5402DD286708E70079C579 /* JDSBNotificationViewController.m in Sources */, 7E5402DE286708E70079C579 /* JDSBNotificationWindow.h in Sources */, 7E5402DF286708E70079C579 /* JDSBNotificationWindow.m in Sources */, - 7E5402E0286708E70079C579 /* JDSystemStatusBarHelpers.h in Sources */, - 7E5402E1286708E70079C579 /* JDSystemStatusBarHelpers.m in Sources */, 7E5402E2286708E70079C579 /* UIApplication+JDSB_MainWindow.h in Sources */, 7E5402E3286708E70079C579 /* UIApplication+JDSB_MainWindow.m in Sources */, 7E5402C6286708850079C579 /* JDStatusBarNotification.docc in Sources */, @@ -540,7 +529,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7EA91CAA284EF3AF00F32F09 /* JDSystemStatusBarHelpers.m in Sources */, 7EA91CAB284EF3AF00F32F09 /* JDSBNotificationWindow.m in Sources */, 7E0FCB77285DAEB200E7CB78 /* FontPickerView.swift in Sources */, 7E2F3BBD284F6144002B2181 /* ObservableCustomStyle.swift in Sources */, @@ -568,7 +556,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7EE516D8284711C900685DDF /* JDSystemStatusBarHelpers.m in Sources */, 7ED140932847557600593D6F /* JDSBNotificationWindow.m in Sources */, 7E0FCB76285DAEB200E7CB78 /* FontPickerView.swift in Sources */, 7E2F3BBC284F6144002B2181 /* ObservableCustomStyle.swift in Sources */, @@ -613,7 +600,6 @@ 7E2F3BBB284F6144002B2181 /* ObservableCustomStyle.swift in Sources */, 7E8C51A02858857200C7C003 /* TextStyleEditorView.swift in Sources */, 7E8C519928585BE400C7C003 /* JDStatusBarNotificationStyle.m in Sources */, - 7EE516D7284711C900685DDF /* JDSystemStatusBarHelpers.m in Sources */, 7ED140922847557600593D6F /* JDSBNotificationWindow.m in Sources */, 7EBE34122844CA2D0096CD55 /* UIApplication+JDSB_MainWindow.m in Sources */, 7EBE34162844CA2D0096CD55 /* JDSBNotificationViewController.m in Sources */, diff --git a/JDStatusBarNotification/Private/JDSBNotificationView.m b/JDStatusBarNotification/Private/JDSBNotificationView.m index c25254d3..a7d97642 100644 --- a/JDStatusBarNotification/Private/JDSBNotificationView.m +++ b/JDStatusBarNotification/Private/JDSBNotificationView.m @@ -8,7 +8,6 @@ #import "JDSBNotificationView.h" #import "JDStatusBarNotificationStyle.h" -#import "JDSystemStatusBarHelpers.h" static const NSInteger kExpectedSubviewTag = 12321; @@ -352,13 +351,8 @@ - (void)setPillStyle:(JDStatusBarNotificationPillStyle *)pillStyle { #pragma mark - Layout -static CGRect contentRectForWindow(UIView *view) { - CGFloat topLayoutMargins = view.superview.layoutMargins.top; - if (topLayoutMargins <= 8) { - // ignore default margins, fallback to system status bar height - topLayoutMargins = JDStatusBarFrameForWindowScene(view.window.windowScene).size.height; - } - +static CGRect contentRectForViewMinusSafeAreaInsets(UIView *view) { + CGFloat topLayoutMargins = view.window.safeAreaInsets.top; CGFloat height = view.bounds.size.height - topLayoutMargins; return CGRectMake(0, topLayoutMargins, view.bounds.size.width, height); } @@ -404,11 +398,11 @@ - (void)layoutSubviews { // content & pill view switch (_style.backgroundStyle.backgroundType) { case JDStatusBarNotificationBackgroundTypeFullWidth: { - _contentView.frame = contentRectForWindow(self); + _contentView.frame = contentRectForViewMinusSafeAreaInsets(self); break; } case JDStatusBarNotificationBackgroundTypePill: { - _contentView.frame = [self pillContentRectForContentRect:contentRectForWindow(self)]; + _contentView.frame = [self pillContentRectForContentRect:contentRectForViewMinusSafeAreaInsets(self)]; _pillView.frame = _contentView.bounds; // setup rounded corners (not using a mask layer, so that we can use shadows on this view) diff --git a/JDStatusBarNotification/Private/JDSBNotificationViewController.h b/JDStatusBarNotification/Private/JDSBNotificationViewController.h index 734700e4..a0047ada 100644 --- a/JDStatusBarNotification/Private/JDSBNotificationViewController.h +++ b/JDStatusBarNotification/Private/JDSBNotificationViewController.h @@ -12,7 +12,7 @@ typedef void (^ _Nullable JDSBNotificationViewControllerCompletion)(void) NS_SWI NS_SWIFT_NAME(_SBNotificationViewControllerDelegate) @protocol JDSBNotificationViewControllerDelegate -- (void)animationsForViewTransitionToSize:(CGSize)size; +- (void)relayoutWindowAndStatusBarView; - (void)didDismissStatusBar; - (void)didUpdateStyle; @end diff --git a/JDStatusBarNotification/Private/JDSBNotificationViewController.m b/JDStatusBarNotification/Private/JDSBNotificationViewController.m index f90552ad..0416a375 100644 --- a/JDStatusBarNotification/Private/JDSBNotificationViewController.m +++ b/JDStatusBarNotification/Private/JDSBNotificationViewController.m @@ -235,7 +235,7 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id _Nonnull context) { - [self.delegate animationsForViewTransitionToSize:size]; + [self.delegate relayoutWindowAndStatusBarView]; } completion:^(id _Nonnull context) { // }]; diff --git a/JDStatusBarNotification/Private/JDSBNotificationWindow.m b/JDStatusBarNotification/Private/JDSBNotificationWindow.m index 75b61e0a..e6bfca3f 100644 --- a/JDStatusBarNotification/Private/JDSBNotificationWindow.m +++ b/JDStatusBarNotification/Private/JDSBNotificationWindow.m @@ -7,7 +7,6 @@ #import "JDSBNotificationView.h" #import "JDStatusBarNotificationStyle.h" #import "UIApplication+JDSB_MainWindow.h" -#import "JDSystemStatusBarHelpers.h" @interface JDSBNotificationWindow () @end @@ -42,42 +41,37 @@ - (instancetype)initWithStyle:(JDStatusBarNotificationStyle *)style #pragma mark - Sizing -- (void)updateFramesForStatusBarFrame:(CGRect)rect { +- (void)relayoutWindowAndStatusBarView { // match main window transform & frame UIWindow *window = [[UIApplication sharedApplication] jdsb_mainApplicationWindowIgnoringWindow:self]; self.transform = window.transform; self.frame = window.frame; - // default to window width - if (CGRectIsEmpty(rect)) { - rect = CGRectMake(0, 0, window.frame.size.width, 0.0); - } - - // update top bar frame - JDSBNotificationView *statusBarView = _statusBarViewController.statusBarView; - CGFloat heightIncludingNavBar = rect.size.height + contentHeight(window.windowScene, statusBarView.style, rect); + // resize statusBarView + JDSBNotificationView *const statusBarView = _statusBarViewController.statusBarView; + const CGFloat safeAreaInset = self.safeAreaInsets.top; + const CGFloat heightIncludingNavBar = safeAreaInset + contentHeight(statusBarView.style, safeAreaInset); statusBarView.transform = CGAffineTransformIdentity; - statusBarView.frame = CGRectMake(0, 0, rect.size.width, heightIncludingNavBar); + statusBarView.frame = CGRectMake(0, 0, window.frame.size.width, heightIncludingNavBar); // relayout progress bar [statusBarView setProgressBarPercentage:_statusBarViewController.statusBarView.progressBarPercentage]; } -static CGFloat contentHeight(UIWindowScene *windowScene, JDStatusBarNotificationStyle *style, CGRect statusBarRect) { +static CGFloat contentHeight(JDStatusBarNotificationStyle *style, CGFloat safeAreaInset) { switch (style.backgroundStyle.backgroundType) { case JDStatusBarNotificationBackgroundTypeFullWidth: { - if (([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) && - UIInterfaceOrientationIsLandscape(JDStatusBarOrientationForWindowScene(windowScene))) { - return 32.0; // match navbar height + if (safeAreaInset >= 54.0) { + return 38.66; // for dynamic island devices, this ensures the navbar separator stays visible } else { - return 44.0; // match navbar height + return 44.0; // default navbar height } } case JDStatusBarNotificationBackgroundTypePill: { CGFloat notchAdjustment = 0.0; - if (statusBarRect.size.height >= 54.0) { + if (safeAreaInset >= 54.0) { notchAdjustment = 0.0; // for the dynamic island, utilize the default positioning - } else if (statusBarRect.size.height > 20.0) { + } else if (safeAreaInset > 20.0) { notchAdjustment = -7.0; // this matches the positioning of a similar system notification } else { notchAdjustment = 3.0; // for no-notch devices, default to a minimum spacing @@ -89,17 +83,12 @@ static CGFloat contentHeight(UIWindowScene *windowScene, JDStatusBarNotification #pragma mark - JDSBNotificationViewControllerDelegate -- (void)animationsForViewTransitionToSize:(CGSize)size { - // update window & statusbar - [self updateFramesForStatusBarFrame:CGRectMake(0, 0, size.width, JDStatusBarFrameForWindowScene(self.windowScene).size.height)]; -} - - (void)didDismissStatusBar { [self.delegate didDismissStatusBar]; } - (void)didUpdateStyle { - [self updateFramesForStatusBarFrame:JDStatusBarFrameForWindowScene(self.windowScene)]; + [self relayoutWindowAndStatusBarView]; } #pragma mark - HitTest diff --git a/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.h b/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.h deleted file mode 100644 index d3e06f54..00000000 --- a/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.h +++ /dev/null @@ -1,8 +0,0 @@ -// -// - -#import - -extern CGRect JDStatusBarFrameForWindowScene(UIWindowScene *_Nullable windowScene); - -extern UIInterfaceOrientation JDStatusBarOrientationForWindowScene(UIWindowScene *_Nullable windowScene); diff --git a/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.m b/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.m deleted file mode 100644 index cd82f40d..00000000 --- a/JDStatusBarNotification/Private/JDSystemStatusBarHelpers.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// - -#import "JDSystemStatusBarHelpers.h" - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CGRect JDStatusBarFrameForWindowScene(UIWindowScene *_Nullable windowScene) { - if (windowScene != nil) { - return [[windowScene statusBarManager] statusBarFrame]; - } else { - return [[UIApplication sharedApplication] statusBarFrame]; - } -} - -UIInterfaceOrientation JDStatusBarOrientationForWindowScene(UIWindowScene *_Nullable windowScene) { - if (windowScene != nil) { - return [windowScene interfaceOrientation]; - } else { - return [[UIApplication sharedApplication] statusBarOrientation]; - } -} - -#pragma clang diagnostic pop