Created
August 1, 2024 07:29
-
-
Save howardsilver-macdev/6391794727549ae78847eb743b5e141b to your computer and use it in GitHub Desktop.
Attempt at SwiftUI Sheets That Only Take Up Required Height of Enclosed View
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct ContentView: View { | |
@State private var isSheetPresented: Bool = false | |
@State private var sheetHeight: CGFloat = 0 | |
var body: some View { | |
VStack { | |
Button("See sheet", action: { | |
isSheetPresented.toggle() | |
}) | |
} | |
.padding() | |
.popupSheet(isPresented: $isSheetPresented, onDismiss: { | |
print("Sheet was dismissed") | |
}) { | |
/// | |
/// This does NOT work | |
/// | |
// SheetView1() | |
/// | |
/// This does work!!!! | |
/// | |
VStack { | |
Spacer() | |
Spacer() | |
VStack { | |
Text("Hello, World!") | |
Text("Goodbye, World!") | |
} | |
HStack { | |
Image(systemName: "globe") | |
.imageScale(.large) | |
.foregroundStyle(.tint) | |
Image(systemName: "heart") | |
.imageScale(.large) | |
.foregroundStyle(.red) | |
Image(systemName: "baseball") | |
.imageScale(.large) | |
.foregroundStyle(.primary) | |
Image(systemName: "person.crop.circle") | |
.imageScale(.large) | |
.foregroundStyle(.green) | |
} | |
.padding() | |
} | |
} | |
} | |
} | |
#Preview { | |
ContentView() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct SizePreferenceKey: PreferenceKey { | |
static var defaultValue: CGSize = .zero | |
static func reduce(value: inout CGSize, nextValue: () -> CGSize) { value = nextValue() } | |
} | |
struct PopupSheetModifier<SheetContent: View>: ViewModifier { | |
@Binding var isPresented: Bool | |
@State private var sheetHeight: CGFloat = .zero | |
let onDismiss: (() -> Void)? | |
let content: () -> SheetContent | |
func body(content: Content) -> some View { | |
content | |
.sheet(isPresented: $isPresented, onDismiss: onDismiss) { | |
self.content() | |
.background( | |
GeometryReader { geo in | |
Color.clear | |
.preference(key: SizePreferenceKey.self, value: geo.size) | |
} | |
) | |
.onPreferenceChange(SizePreferenceKey.self) { newSize in | |
sheetHeight = newSize.height | |
print("The sheetHeight is:\(sheetHeight)") | |
} | |
.presentationDetents([.height(sheetHeight)]) | |
.frame(minHeight: sheetHeight, maxHeight: sheetHeight) | |
.presentationDragIndicator(.hidden) | |
} | |
} | |
} | |
extension View { | |
func popupSheet<SheetContent: View>( | |
isPresented: Binding<Bool>, | |
onDismiss: (() -> Void)? = nil, | |
@ViewBuilder content: @escaping () -> SheetContent | |
) -> some View { | |
self.modifier(PopupSheetModifier(isPresented: isPresented, onDismiss: onDismiss, content: content)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct SheetView1: View { | |
var body: some View { | |
VStack { | |
Spacer() | |
Spacer() | |
VStack { | |
Text("Hello, World!") | |
Text("Goodbye, World!") | |
} | |
HStack { | |
Image(systemName: "globe") | |
.imageScale(.large) | |
.foregroundStyle(.tint) | |
Image(systemName: "heart") | |
.imageScale(.large) | |
.foregroundStyle(.red) | |
Image(systemName: "baseball") | |
.imageScale(.large) | |
.foregroundStyle(.primary) | |
Image(systemName: "person.crop.circle") | |
.imageScale(.large) | |
.foregroundStyle(.green) | |
} | |
.padding() | |
} | |
} | |
} | |
#Preview { | |
SheetView1() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment