Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
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) {
24 guard let sheet = self.sheetPresentationController,
25 let screenHeight = Util.getScreenHeight()
26 else {
27 return
28 }
29
30 // On iOS 26, the floaty sheet presentation adds the device bottom safe area
31 // on top of the custom detent value, creating visible padding inside the pill.
32 // Subtract it so the pill height matches our actual content.
33 var bottomSafeAreaAdjustment: CGFloat = 0
34 if #available(iOS 26.0, *) {
35 if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
36 let window = windowScene.windows.first {
37 bottomSafeAreaAdjustment = window.safeAreaInsets.bottom
38 }
39 }
40
41 let adjustedHeight = contentHeight - bottomSafeAreaAdjustment
42
43 if #available(iOS 16.0, *) {
44 if contentHeight > screenHeight - 100 {
45 sheet.detents = [
46 .large()
47 ]
48 sheet.selectedDetentIdentifier = .large
49 } else {
50 sheet.detents = [
51 .custom { _ in
52 return adjustedHeight
53 }
54 ]
55 if !preventExpansion {
56 sheet.detents.append(.large())
57 }
58 sheet.selectedDetentIdentifier = .medium
59 }
60 } else {
61 if contentHeight > screenHeight / 2 {
62 sheet.detents = [
63 .large()
64 ]
65 sheet.selectedDetentIdentifier = .large
66 } else {
67 sheet.detents = [
68 .medium()
69 ]
70 if !preventExpansion {
71 sheet.detents.append(.large())
72 }
73 sheet.selectedDetentIdentifier = .medium
74 }
75 }
76 }
77
78 func updateDetents(contentHeight: CGFloat, preventExpansion: Bool) {
79 if let sheet = self.sheetPresentationController {
80 // Capture `self` weakly to prevent retain cycles.
81 // Also, capture `sheet` weakly to avoid potential strong references held by animateChanges.
82 sheet.animateChanges { [weak self, weak sheet] in
83 guard let weakSelf = self, let weakSheet = sheet else { return }
84 weakSelf.setDetents(contentHeight: contentHeight, preventExpansion: preventExpansion)
85 if #available(iOS 16.0, *) {
86 weakSheet.invalidateDetents()
87 }
88 }
89 }
90 }
91
92 func getCurrentDetentIdentifier() -> UISheetPresentationController.Detent.Identifier? {
93 guard let sheet = self.sheetPresentationController else {
94 return nil
95 }
96 return sheet.selectedDetentIdentifier
97 }
98
99 required init?(coder: NSCoder) {
100 fatalError("init(coder:) has not been implemented")
101 }
102}