Skip to content

Commit 561be6f

Browse files
authored
Fix crash when opening message overlay in iPad with a TabBar (#627)
1 parent b16cd5b commit 561be6f

File tree

4 files changed

+29
-16
lines changed

4 files changed

+29
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44
# Upcoming
55

6-
### 🔄 Changed
6+
### 🐞 Fixed
7+
- Fix crash when opening message overlay in iPad with a TabBar [#627](https://github.com/GetStream/stream-chat-swiftui/pull/627)
78

89
# [4.65.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.65.0)
910
_October 18, 2024_

Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
7171
currentSnapshot: currentSnapshot,
7272
popInAnimationInProgress: !popIn
7373
)
74-
.offset(y: spacing > 0 ? screenHeight - currentSnapshot.size.height : 0)
74+
.offset(y: overlayOffsetY)
7575
} else {
7676
Color.gray.opacity(0.4)
7777
}
@@ -290,7 +290,16 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
290290

291291
return originY - spacing
292292
}
293-
293+
294+
private var overlayOffsetY: CGFloat {
295+
if isIPad && UITabBar.appearance().isHidden == false {
296+
// When using iPad with TabBar, this hard coded value makes
297+
// sure that the overlay is in the correct position.
298+
return 20
299+
}
300+
return spacing > 0 ? screenHeight - currentSnapshot.size.height : 0
301+
}
302+
294303
private var spacing: CGFloat {
295304
let divider: CGFloat = isIPad ? 2 : 1
296305
let spacing = (UIScreen.main.bounds.height - screenHeight) / divider

Sources/StreamChatSwiftUI/ChatChannel/Utils/ChatChannelHelpers.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ public struct BottomLeftView<Content: View>: View {
8282

8383
/// Returns the top most view controller.
8484
func topVC() -> UIViewController? {
85+
// TODO: Refactor ReactionsOverlayView to use a background blur, instead of a snapshot.
86+
/// Since the current approach is too error-prone and dependent of the app's hierarchy,
87+
8588
let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
8689

8790
if var topController = keyWindow?.rootViewController {
@@ -92,10 +95,16 @@ func topVC() -> UIViewController? {
9295
if UIDevice.current.userInterfaceIdiom == .pad {
9396
let children = topController.children
9497
if !children.isEmpty {
95-
let splitVC = children[0]
96-
let sideVCs = splitVC.children
97-
if sideVCs.count > 1 {
98-
topController = sideVCs[1]
98+
if let splitVC = children[0] as? UISplitViewController,
99+
let contentVC = splitVC.viewControllers.last {
100+
topController = contentVC
101+
return topController
102+
} else if let tabVC = children[0] as? UITabBarController,
103+
let selectedVC = tabVC.selectedViewController {
104+
// If the selectedVC is split view, we need to grab the content view of it
105+
// other wise, the selectedVC is already the content view.
106+
let selectedContentVC = selectedVC.children.first?.children.last?.children.first
107+
topController = selectedContentVC ?? selectedVC
99108
return topController
100109
}
101110
}

Sources/StreamChatSwiftUI/Utils/SnapshotCreator.swift

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,9 @@ public class DefaultSnapshotCreator: SnapshotCreator {
2828
}
2929

3030
func makeSnapshot(from view: UIView) -> UIImage {
31-
let currentSnapshot: UIImage?
32-
UIGraphicsBeginImageContext(view.frame.size)
33-
if let currentGraphicsContext = UIGraphicsGetCurrentContext() {
34-
view.layer.render(in: currentGraphicsContext)
35-
currentSnapshot = UIGraphicsGetImageFromCurrentImageContext()
36-
} else {
37-
currentSnapshot = images.snapshot
31+
let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
32+
return renderer.image { _ in
33+
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
3834
}
39-
UIGraphicsEndImageContext()
40-
return currentSnapshot ?? images.snapshot
4135
}
4236
}

0 commit comments

Comments
 (0)