forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1//
2// SheetViewController.swift
3// Pods
4//
5// Created by Hailey on 9/30/24.
6//
7
8import Foundation
9import UIKit
10
11class SheetViewController: UIViewController {
12 init() {
13 super.init(nibName: nil, bundle: nil)
14
15 self.modalPresentationStyle = .formSheet
16 self.isModalInPresentation = false
17
18 if let sheet = self.sheetPresentationController {
19 sheet.prefersGrabberVisible = false
20 }
21 }
22
23 func setDetents(contentHeight: CGFloat, preventExpansion: Bool, fullHeight: Bool = false) {
24 guard let sheet = self.sheetPresentationController,
25 let screenHeight = Util.getScreenHeight()
26 else {
27 return
28 }
29
30 if fullHeight {
31 sheet.detents = [.large()]
32 sheet.selectedDetentIdentifier = .large
33 return
34 }
35
36 // On iOS 26, the floaty sheet presentation adds the device bottom safe area
37 // on top of the custom detent value, creating visible padding inside the pill.
38 // Subtract it so the pill height matches our actual content.
39 var bottomSafeAreaAdjustment: CGFloat = 0
40 if #available(iOS 26.0, *) {
41 if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
42 let window = windowScene.windows.first {
43 bottomSafeAreaAdjustment = window.safeAreaInsets.bottom
44 }
45 }
46
47 let adjustedHeight = contentHeight - bottomSafeAreaAdjustment
48
49 if #available(iOS 16.0, *) {
50 if contentHeight > screenHeight - 100 {
51 sheet.detents = [
52 .large()
53 ]
54 sheet.selectedDetentIdentifier = .large
55 } else {
56 sheet.detents = [
57 .custom { _ in
58 return adjustedHeight
59 }
60 ]
61 if !preventExpansion {
62 sheet.detents.append(.large())
63 }
64 sheet.selectedDetentIdentifier = .medium
65 }
66 } else {
67 if contentHeight > screenHeight / 2 {
68 sheet.detents = [
69 .large()
70 ]
71 sheet.selectedDetentIdentifier = .large
72 } else {
73 sheet.detents = [
74 .medium()
75 ]
76 if !preventExpansion {
77 sheet.detents.append(.large())
78 }
79 sheet.selectedDetentIdentifier = .medium
80 }
81 }
82 }
83
84 func updateDetents(contentHeight: CGFloat, preventExpansion: Bool) {
85 if let sheet = self.sheetPresentationController {
86 // Capture `self` weakly to prevent retain cycles.
87 // Also, capture `sheet` weakly to avoid potential strong references held by animateChanges.
88 sheet.animateChanges { [weak self, weak sheet] in
89 guard let weakSelf = self, let weakSheet = sheet else { return }
90 weakSelf.setDetents(contentHeight: contentHeight, preventExpansion: preventExpansion)
91 if #available(iOS 16.0, *) {
92 weakSheet.invalidateDetents()
93 }
94 }
95 }
96 }
97
98 func getCurrentDetentIdentifier() -> UISheetPresentationController.Detent.Identifier? {
99 guard let sheet = self.sheetPresentationController else {
100 return nil
101 }
102 return sheet.selectedDetentIdentifier
103 }
104
105 required init?(coder: NSCoder) {
106 fatalError("init(coder:) has not been implemented")
107 }
108}