From 9fa980bdf963020ef5a67b773bb3372572dd28f5 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Mon, 21 Oct 2024 18:02:00 +0100 Subject: [PATCH 1/3] Fix crash when opening message overlay in iPad with a TabBar --- .../Reactions/ReactionsOverlayView.swift | 13 +++++++++++-- .../ChatChannel/Utils/ChatChannelHelpers.swift | 17 +++++++++++++---- .../Utils/SnapshotCreator.swift | 12 +++--------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift index 28f7f4246..1741728ee 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift @@ -71,7 +71,7 @@ public struct ReactionsOverlayView: View { currentSnapshot: currentSnapshot, popInAnimationInProgress: !popIn ) - .offset(y: spacing > 0 ? screenHeight - currentSnapshot.size.height : 0) + .offset(y: overlayOffsetY) } else { Color.gray.opacity(0.4) } @@ -290,7 +290,16 @@ public struct ReactionsOverlayView: View { return originY - spacing } - + + private var overlayOffsetY: CGFloat { + if isIPad && UITabBar.appearance().isHidden == false { + // When using iPad with TabBar, this hard coded value makes + // sure that the overlay is in the correct position. + return 20 + } + return spacing > 0 ? screenHeight - currentSnapshot.size.height : 0 + } + private var spacing: CGFloat { let divider: CGFloat = isIPad ? 2 : 1 let spacing = (UIScreen.main.bounds.height - screenHeight) / divider diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Utils/ChatChannelHelpers.swift b/Sources/StreamChatSwiftUI/ChatChannel/Utils/ChatChannelHelpers.swift index ee9fcec65..e03704ced 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Utils/ChatChannelHelpers.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Utils/ChatChannelHelpers.swift @@ -82,6 +82,9 @@ public struct BottomLeftView: View { /// Returns the top most view controller. func topVC() -> UIViewController? { + // TODO: Refactor ReactionsOverlayView to use a background blur, instead of a snapshot. + /// Since the current approach is too error-prone and dependent of the app's hierarchy, + let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first if var topController = keyWindow?.rootViewController { @@ -92,10 +95,16 @@ func topVC() -> UIViewController? { if UIDevice.current.userInterfaceIdiom == .pad { let children = topController.children if !children.isEmpty { - let splitVC = children[0] - let sideVCs = splitVC.children - if sideVCs.count > 1 { - topController = sideVCs[1] + if let splitVC = children[0] as? UISplitViewController, + let contentVC = splitVC.viewControllers.last { + topController = contentVC + return topController + } else if let tabVC = children[0] as? UITabBarController, + let selectedVC = tabVC.selectedViewController { + // If the selectedVC is split view, we need to grab the content view of it + // other wise, the selectedVC is already the content view. + let selectedContentVC = selectedVC.children.first?.children.last?.children.first + topController = selectedContentVC ?? selectedVC return topController } } diff --git a/Sources/StreamChatSwiftUI/Utils/SnapshotCreator.swift b/Sources/StreamChatSwiftUI/Utils/SnapshotCreator.swift index af4aed693..adcfedcee 100644 --- a/Sources/StreamChatSwiftUI/Utils/SnapshotCreator.swift +++ b/Sources/StreamChatSwiftUI/Utils/SnapshotCreator.swift @@ -28,15 +28,9 @@ public class DefaultSnapshotCreator: SnapshotCreator { } func makeSnapshot(from view: UIView) -> UIImage { - let currentSnapshot: UIImage? - UIGraphicsBeginImageContext(view.frame.size) - if let currentGraphicsContext = UIGraphicsGetCurrentContext() { - view.layer.render(in: currentGraphicsContext) - currentSnapshot = UIGraphicsGetImageFromCurrentImageContext() - } else { - currentSnapshot = images.snapshot + let renderer = UIGraphicsImageRenderer(size: view.bounds.size) + return renderer.image { _ in + view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) } - UIGraphicsEndImageContext() - return currentSnapshot ?? images.snapshot } } From 11474d9fce4f0b2d904d885dc8604904d42a48fa Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Mon, 21 Oct 2024 18:13:10 +0100 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8abaa99..e55c8924b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Upcoming -### 🔄 Changed +### 🐞 Fixed +-Fix crash when opening message overlay in iPad with a TabBar [#627](https://github.com/GetStream/stream-chat-swiftui/pull/627) # [4.65.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.65.0) _October 18, 2024_ From 04efba39cdb036fd2bb382acccae84ebd3618221 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Mon, 21 Oct 2024 18:13:37 +0100 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e55c8924b..e363a2b6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Upcoming ### 🐞 Fixed --Fix crash when opening message overlay in iPad with a TabBar [#627](https://github.com/GetStream/stream-chat-swiftui/pull/627) +- Fix crash when opening message overlay in iPad with a TabBar [#627](https://github.com/GetStream/stream-chat-swiftui/pull/627) # [4.65.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.65.0) _October 18, 2024_