Mastering PresentationDetent in SwiftUI: A Comprehensive Guide

Wesley Matlock
4 min readJun 4, 2024

--

Welcome to this comprehensive guide on using PresentationDetent in SwiftUI. PresentationDetent is a powerful feature that allows developers to control the size of presented sheets. This guide will walk you through the basics, implementation, and advanced use cases, enabling you to create dynamic and interactive user interfaces.

Setting Up the Project

First, let’s set up a new SwiftUI project in Xcode. Ensure you have the latest version of Xcode and that your project targets iOS 15.0 or later, as PresentationDetent is available from iOS 15 onwards.

Understanding PresentationDetent

PresentationDetent controls the height of a sheet in SwiftUI. It offers several built-in options:

• .medium

• .large

• .fraction

• .height

These detents allow for various heights, ranging from preset sizes to customizable fractions and specific heights.

Implementing PresentationDetent in SwiftUI

Step 1: Basic Setup

Let’s start with a basic example. Create a simple SwiftUI view with a button to present a sheet.

import SwiftUI

struct ContentView: View {
@State private var showSheet = false

var body: some View {
VStack {
Button("Show Sheet") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
SheetView()
.presentationDetents([.medium, .large])
}
}
}
}

struct SheetView: View {
var body: some View {
VStack {
Text("This is a sheet view")
// Add more content here
}
.padding()
}
}

Step 2: Customizing Detents

You can customize the detents by adding .fraction and .height.

.presentationDetents([.medium, .large, .fraction(0.25), .height(200)])

This flexibility allows you to specify exact sizes or percentages of the screen.

Step 3: Adding Dynamic Content

Now, let’s see how dynamic content affects the sheet size.

struct DynamicContentSheetView: View {
@State private var items = ["Item 1", "Item 2"]

var body: some View {
VStack {
List(items, id: \.self) { item in
Text(item)
}
Button("Add Item") {
items.append("Item \(items.count + 1)")
}
}
.padding()
}
}

Handling State and Logic

Managing state within the presented view is crucial for interactive applications. Here’s an example:

struct SheetView: View {
@State private var count = 0

var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
}
.padding()
}
}

Advanced Use Cases

Using PresentationDetent with NavigationView

Presenting a NavigationView within a sheet can be useful for creating navigable interfaces.

struct ContentView: View {
@State private var showSheet = false

var body: some View {
VStack {
Button("Show Sheet with Navigation") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
NavigationSheetView()
.presentationDetents([.medium, .large])
}
}
}
}

struct NavigationSheetView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: DetailView(item: "Item 1")) {
Text("Item 1")
}
NavigationLink(destination: DetailView(item: "Item 2")) {
Text("Item 2")
}
}
.navigationTitle("Items")
}
}
}

struct DetailView: View {
let item: String

var body: some View {
Text("Details about \(item)")
.navigationTitle(item)
}
}

Using PresentationDetent with Custom Detents

Custom detents using .fraction and .height allow precise control over the sheet size.

struct ContentView: View {
@State private var showSheet = false

var body: some View {
VStack {
Button("Show Custom Detent Sheet") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
CustomDetentSheetView()
.presentationDetents([.fraction(0.3), .height(400)])
}
}
}
}

struct CustomDetentSheetView: View {
var body: some View {
VStack {
Text("This sheet uses custom detents")
// Additional content
}
.padding()
}
}

Combining Multiple Advanced Features

You can combine multiple advanced features to create sophisticated and dynamic sheets.

struct ContentView: View {
@State private var showSheet = false

var body: some View {
VStack {
Button("Show Advanced Sheet") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
AdvancedSheetView()
.presentationDetents([.medium, .fraction(0.5), .height(500)])
}
}
}
}

struct AdvancedSheetView: View {
@State private var items = ["Item 1", "Item 2"]

var body: some View {
NavigationView {
VStack {
List(items, id: \.self) { item in
NavigationLink(destination: DetailView(item: item)) {
Text(item)
}
}
Button("Add Item") {
items.append("Item \(items.count + 1)")
}
}
.navigationTitle("Dynamic Items")
.padding()
}
}
}

struct DetailView: View {
let item: String

var body: some View {
Text("Details about \(item)")
.navigationTitle(item)
}
}

Conclusion

In this guide, we’ve explored the basics and advanced uses of PresentationDetent in SwiftUI. Whether you’re using it with NavigationView, handling dynamic content, or customizing detents, PresentationDetent allows you to create engaging and interactive user interfaces. Experiment with these features and adapt them to your projects to enhance your app’s user experience.

By following this structured and detailed guide, your readers will gain a thorough understanding of how to use PresentationDetent in SwiftUI effectively.

If you want to learn more about native mobile development, you can check out the other articles I have written here: https://medium.com/@wesleymatlock

Happy coding! 🚀

--

--