Swift弹出sheet视图
Swift弹出sheet视图

Swift弹出sheet视图

在Swift中,sheet 是一个用于显示模态视图(Modal View)的功能,通常在SwiftUI框架中使用。模态视图是一个临时的、覆盖在主界面上的视图,用户需要完成某些任务或交互后才能返回主视图。

基本用法

sheet 是一个视图修饰符,绑定到一个布尔值或可选值,当条件满足时,会呈现一个模态视图。

基本语法

.sheet(isPresented: $isSheetPresented) {
    // 显示的内容
    YourView()
}

示例

import SwiftUI

struct ContentView: View {
    @State private var isSheetPresented = false
    
    var body: some View {
        VStack {
            Button("显示模态视图") {
                isSheetPresented = true
            }
        }
        .sheet(isPresented: $isSheetPresented) {
            Text("这是一个模态视图")
                .font(.largeTitle)
        }
    }
}

使用可选值触发

也可以使用sheet(item:binding:),当一个可选值(如Optional)不为nil时,显示模态视图。

示例

struct Item: Identifiable {
    let id = UUID()
    let name: String
}

struct ContentView: View {
    @State private var selectedItem: Item? = nil

    var body: some View {
        VStack {
            Button("选择项目") {
                selectedItem = Item(name: "示例项目")
            }
        }
        .sheet(item: $selectedItem) { item in
            Text("选中了: \(item.name)")
                .font(.title)
        }
    }
}

模态视图的自定义

模态视图可以包含复杂的UI,甚至嵌套其他视图。

示例:复杂模态视图

struct someView: View {
    @State private var isSheetPresented = false
    
    var body: some View {
        VStack {
            Button("打开模态视图") {
                isSheetPresented = true
            }
        }
        .sheet(isPresented: $isSheetPresented) {
            ModalView()
        }
    }
}

struct ModalView: View {
    @Environment(\.dismiss) var dismiss
    var body: some View {
        VStack {
            Text("这是一个模态视图")
                .font(.headline)
            Button("关闭") {
                dismiss()
                // 通常由父视图的绑定控制关闭逻辑
                // 在实际项目中,这个按钮的动作会回调父视图的状态更新
            }
        }
    }
}

模态视图关闭

在SwiftUI中,模态视图的关闭通常由绑定的状态值(如isPresented)控制。当需要手动关闭模态视图时,可以直接修改绑定值。例如,将isSheetPresented设为false。

示例

struct ContentView: View {
    @State private var isSheetPresented = false
    
    var body: some View {
        VStack {
            Button("显示模态视图") {
                isSheetPresented = true
            }
        }
        .sheet(isPresented: $isSheetPresented) {
            VStack {
                Text("这是一个模态视图")
                    .font(.largeTitle)
                Button("关闭") {
                    isSheetPresented = false
                }
            }
        }
    }
}

onDismiss参数

在 SwiftUI 中,onDismiss: 是一个参数,用于在 sheet 模态视图被关闭时触发某个操作。具体来说,onDismiss:表示当sheet的模态视图被关闭时,会自动调用其方法。

示例代码

.sheet(isPresented: $showingEditScreen, onDismiss: resetCards) {
    EditCards()
}

onDismiss: resetCards: 当 EditCards 被关闭(例如用户手动滑下关闭)时,会调用 resetCards()。

为什么需要 onDismiss?

可能希望在模态视图关闭后执行某些动作,例如:

刷新数据。

重置某些状态。

保存或清理用户输入。

小结

onDismiss: 的作用是 在模态视图关闭时触发重置动作,以保证应用的状态与预期一致。这种方式可以很好地维护界面逻辑的流畅性,避免用户的操作或数据遗漏引发问题。

Init()初始化器

1、.sheet() 的正常用法

通常,.sheet() 的 content 参数 需要一个闭包,该闭包返回一个视图。

例如

.sheet(isPresented: $showingEditScreen, onDismiss: resetCards) {
    EditCards()
}

在这里,{ EditCards() } 是一个闭包,它返回 EditCards 视图的实例。

2、Swift 的“语法糖”

EditCards() 实际上是使用了 Swift 的语法糖,它等同于调用 EditCards 的初始化器 EditCards.init(),因为 EditCards 是一个结构体,其默认初始化器 init() 可以用来创建实例。

所以,以下两种写法是等效的:

EditCards()
EditCards.init()

3、优化写法

既然 EditCards() 是初始化器 EditCards.init() 的简写,content: 参数本质上需要的是一个返回视图的函数,我们就可以直接将初始化器 EditCards.init 作为参数传递,而不需要额外的闭包包装。

.sheet(isPresented: $showingEditScreen, onDismiss: resetCards) {
    EditCards()
}

可以简化成这样:

.sheet(isPresented: $showingEditScreen, onDismiss: resetCards, content: EditCards.init)

在这个写法中

EditCards.init 是初始化器的引用,SwiftUI 会自动调用它来创建 EditCards 视图。

4、为什么可以直接使用初始化器?

在 Swift 中,初始化器(init)本质上是一个特殊的函数,可以被传递或调用。.sheet() 的 content 参数需要一个返回视图的函数,而 EditCards.init 完全符合这个要求。

注意事项

1、仅限一次显示一个模态视图: 如果试图同时触发多个sheet,SwiftUI会根据条件的先后显示一个。

2、支持动画过渡: sheet的展示和关闭具有默认的过渡动画。

3、与NavigationView的交互: 模态视图内部可以使用NavigationView实现导航功能。

扩展知识

presentationDetents修饰符

如果想要自定义弹出的Sheet尺寸,可以使用presentationDetents修饰符。

.sheet(isPresented: $isPresented) {
    Text("This is a sheet")
        .presentationDetents([.medium, .large])
}

presentationDetents([.medium, .large]): 设置弹出的 Sheet 可以在 中等高度 和 全屏高度 之间切换。

.medium 和 .large 是预定义的高度类型。

相关知识可以了解《SwiftUI自定义弹出的Sheet的尺寸

相关文章

Sheet嵌套Sheet页返回问题:https://fangjunyu.com/2024/10/19/swift-%e5%b5%8c%e5%a5%97sheet%e9%a1%b5%e8%bf%94%e5%9b%9e%e9%97%ae%e9%a2%98/

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注