SwiftUI Sheet 彈窗與表單教學

除了導航跳轉,我們常需要「由下而上」滑出一張卡片來顯示詳情或輸入資料,這在 SwiftUI 中稱為 Sheet (表單)

Sheet (半頁彈窗)

Sheet 是一個模態視圖 (Modal View),預設無法透過滑動關閉(除非實作了關閉按鈕或是 iOS 13+ 的下滑手勢)。

struct ContentView: View {
    @State private var showSheet = false
    
    var body: some View {
        Button("打開 Sheet") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            SheetView() // 這裡放入你想彈出的 View
        }
    }
}

struct SheetView: View {
    @Environment(\.dismiss) var dismiss // 取得關閉視窗的方法
    
    var body: some View {
        Button("關閉") {
            dismiss()
        }
    }
}

控制 Sheet 的高度 (Presentation Detents)

在 iOS 16+,你可以控制 Sheet 彈出的高度,例如只彈出一半。

.sheet(isPresented: $showSheet) {
    SheetView()
        .presentationDetents([.medium, .large]) // 支援半開和全開
        .presentationDragIndicator(.visible) // 顯示頂部的灰色小橫條
}

FullScreenCover (全螢幕彈窗)

如果你希望彈出的畫面完全蓋住底下的內容(包含狀態列),請使用 fullScreenCover。它的用法跟 sheet 完全一樣。

.fullScreenCover(isPresented: $showSheet) {
    LoginView() // 例如登入頁面通常是全螢幕的
}

Popover (氣泡彈窗)

在 iPad 或 macOS 上,我們常用指著某個按鈕跳出的氣泡視窗。在 iPhone 上,Popover 通常會自動轉成 Sheet 顯示。

Button("選項") {
    showPopover = true
}
.popover(isPresented: $showPopover) {
    Text("這是一個氣泡")
        .padding()
}

了解不同的彈窗方式,可以幫助你根據內容的重要性選擇最適合的呈現手法。