From e24a67023eb3b6b960345b7cf4734932eb9be812 Mon Sep 17 00:00:00 2001 From: Markus Emrich Date: Wed, 18 Oct 2023 21:44:44 +0200 Subject: [PATCH] add sizingController --- .../Private/JDSBNotificationView.m | 3 +++ .../Public/JDStatusBarNotificationPresenter.h | 26 +++++++++++++++++++ .../Public/JDStatusBarNotificationPresenter.m | 10 +++++++ .../JDStatusBarNotificationPresenter.swift | 12 +++++++++ 4 files changed, 51 insertions(+) diff --git a/JDStatusBarNotification/Private/JDSBNotificationView.m b/JDStatusBarNotification/Private/JDSBNotificationView.m index f1674ed0..88027e64 100644 --- a/JDStatusBarNotification/Private/JDSBNotificationView.m +++ b/JDStatusBarNotification/Private/JDSBNotificationView.m @@ -386,6 +386,9 @@ - (CGRect)pillContentRectForContentRect:(CGRect)contentRect { // layout pill CGFloat maxTextWidth = MAX(realTextSizeForLabel(_titleLabel).width, realTextSizeForLabel(_subtitleLabel).width); + if (_customSubview) { + maxTextWidth = MAX(maxTextWidth, [_customSubview sizeThatFits:contentRect.size].width); + } CGFloat pillWidth = round(MAX(minimumPillWidth, MIN(maximumPillWidth, maxTextWidth + paddingX * 2))); CGFloat pillX = round(MAX(minimumPillInset, (CGRectGetWidth(self.bounds) - pillWidth)/2.0)); CGFloat pillY = round(contentRect.origin.y + contentRect.size.height - pillHeight); diff --git a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.h b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.h index 4612cf4d..c2db311a 100644 --- a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.h +++ b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.h @@ -22,6 +22,11 @@ typedef void (^ _Nullable JDStatusBarNotificationPresenterCompletionBlock)(JDSta NS_ASSUME_NONNULL_BEGIN +NS_SWIFT_NAME(NotificationPresenterCustomViewSizingController) +@protocol JDStatusBarNotificationPresenterCustomViewSizingController +- (CGSize)sizeThatFits:(CGSize)size NS_SWIFT_NAME(sizeThatFits(in:)); +@end + /** * The NotificationPresenter let's you present notifications below the statusBar. * You can customize the style (colors, fonts, etc.) and animations. It supports notch @@ -242,6 +247,27 @@ NS_SWIFT_NAME(NotificationPresenter) styleName:(NSString * _Nullable)styleName completion:(JDStatusBarNotificationPresenterCompletionBlock)completion NS_SWIFT_NAME(present(customView:style:completion:)); +/// Present a notification using a custom subview. +/// +/// The `customView` will be layouted correctly according to the selected style & the current device +/// state (rotation, status bar visibility, etc.). The background will still be styled & layouted +/// according to the provided style. If your custom view requires custom touch handling, +/// make sure to set `style.canTapToHold` to `false`. Otherwise the `customView` won't +/// receive any touches, as the internal `gestureRecognizer` would receive them. +/// +/// - Parameters: +/// - customView: A custom UIView to display as notification content. +/// - styleName: The name of the style. You can use styles previously added using e.g. ``addStyleNamed:prepare:``. +/// If no style can be found for the given `styleName` or it is `nil`, the default style will be used. +/// - completion: A ``JDStatusBarNotificationPresenterCompletionBlock``, which gets called once the presentation animation finishes. +/// +/// - Returns: The presented UIView for further customization +/// +- (UIView *)presentWithCustomView:(UIView *)customView + sizingController:(id _Nullable)sizingController + styleName:(NSString * _Nullable)styleName + completion:(JDStatusBarNotificationPresenterCompletionBlock)completion NS_SWIFT_NAME(present(customView:sizingController:style:completion:)); + #pragma mark - Dismissal /// Dismisses any currently displayed notification immediately using an animation. diff --git a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.m b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.m index e63beda6..d8c3578a 100644 --- a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.m +++ b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.m @@ -178,6 +178,16 @@ - (UIView *)presentWithTitle:(NSString *)title - (UIView *)presentWithCustomView:(UIView *)customView styleName:(NSString * _Nullable)styleName completion:(JDStatusBarNotificationPresenterCompletionBlock)completion { + return [self presentWithCustomView:customView + sizingController:nil + styleName:styleName + completion:completion]; +} + +- (UIView *)presentWithCustomView:(UIView *)customView + sizingController:(id _Nullable)sizingController + styleName:(NSString * _Nullable)styleName + completion:(JDStatusBarNotificationPresenterCompletionBlock)completion { JDStatusBarNotificationStyle *style = [_styleCache styleForName:styleName]; JDSBNotificationView *view = [self presentWithTitle:nil subtitle:nil style:style completion:completion]; view.customSubview = customView; diff --git a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.swift b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.swift index bb077bab..d841ea1f 100644 --- a/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.swift +++ b/JDStatusBarNotification/Public/JDStatusBarNotificationPresenter.swift @@ -7,6 +7,18 @@ import SwiftUI +class NotificationPresenterSizingController: NotificationPresenterCustomViewSizingController where Content: View { + let hostingController: UIHostingController + + init(hostingController: UIHostingController) { + self.hostingController = hostingController + } + + func sizeThatFits(in size: CGSize) -> CGSize { + return hostingController.sizeThatFits(in: size) + } +} + extension NotificationPresenter { public func presentSwiftView(style: String? = nil,