SwiftUI:Sheet 视图

在SwiftUI中,有几种显示视图的方法,其中最基本的一种是工作表:在我们现有视图之上显示一个新视图。在iOS上,这会自动为我们提供类似于卡片的演示,其中,当前视图会向远处滑动一点,新视图会在顶部显示动画。(这个和UIKit的模态视图一模一样,就是iOS13之后默认的modalPresentationStyle被设定为UIModalPresentationAutomatic,而这个在iOS 13会指定为 UIModalPresentationPageSheet,在其他老一点的系统还是原来的UIModalPresentationFullScreen,所以小伙伴们现在需要手动指定为UIModalPresentationFullScreen)。

工作表的工作方式与警报非常相似,因为我们不会直接使用mySheet.present()之类的代码来显示工作表。取而代之的是,我们定义了要显示一个sheet的条件,当这些条件变为真或假时,将分别显示或取消该工作表。

让我们从一个简单的示例开始,它将使用工作表显示一个视图与另一个视图。首先,我们创建要显示在工作表中的视图,如下所示:

struct SecondView: View {
    var body: some View {
        Text("Second View")
    }
}

该视图没有什么特别的——它不知道要在工作表中显示,也不需要知道要在工作表中显示。

接下来,我们创建初始视图,该视图将显示第二个视图。我们将使其简化,然后添加到其中:

struct ContentView: View { 
    var body: some View {
        Button("Show Sheet") {
            // show the sheet
        }
    }
}

填写此内容需要四个步骤,我们将逐一解决。

首先,我们需要某种状态来跟踪工作表是否正在显示。就像警报一样,这可以是一个简单的布尔值,因此现在将此属性添加到ContentView

@State private var showingSheet = false

其次,我们需要在点击按钮时进行切换,因此用下方代码替换注释// show the sheet

self.showingSheet.toggle()

第三,我们需要将工作表附加到视图层次结构的某处。如果您还记得的话,我们将使用alert(isPresented:)并将警报与state属性进行双向绑定来显示警报,这和在此处的使用几乎相同:sheet(isPresented:)

sheet()就像alert()一样是一个修饰符,因此请现在将此修饰符添加到我们的按钮中:

.sheet(isPresented: $showingSheet) {
    // contents of the sheet
}

第四,我们需要确定表单中应实际包含的内容。在我们的例子中,我们已经确切知道了我们想要的是什么:我们想要创建并显示SecondView的实例。在代码中,这意味着编写SecondView(),然后…嗯…就是这样。

因此,完成的ContentView结构应如下所示:

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

    var body: some View {
        Button("Show Sheet") {
            self.showingSheet.toggle()
        }
        .sheet(isPresented: $showingSheet) {
            SecondView()
        }
    }
}

如果您现在运行该程序,则会看到您可以点击按钮,使第二个视图从底部向上滑动,然后将其向下拖动以将其关闭。

创建这样的视图时,可以传入需要工作的任何参数。例如,我们可以要求为SecondView发送一个可以显示的名称,如下所示:

struct SecondView: View {
    var name: String

    var body: some View {
        Text("Hello, \(name)!")
    }
}

现在仅在工作表中使用SecondView()还不够——我们需要传递一个名称字符串以显示出来。例如,我们可以这样输入我的用户名:

.sheet(isPresented: $showingSheet) {
    SecondView(name: "韦弦zhy")
}

现在工作表将显示“ Hello,韦弦zhy”。

Swift在这里代表我们做了很多工作:一旦我们说SecondView具有name属性,Swift确保我们的代码甚至都不会编译,直到SecondView()的所有实例都变成SecondView(name:“ some name”),从而消除了所有可能的错误。

在继续之前,我还要演示另一件事,即如何使视图自行关闭。是的,您已经看到用户可以向下滑动,但是有时您可能需要以编程方式关闭视图,例如通过按下按钮使视图消失。

SwiftUI提供了两种方法来执行此操作,但最简单的方法是使用另一个属性包装器——是的,我意识到,解决SwiftUI问题的方法通常是使用另一个属性包装器。

无论如何,这个称为@Environment,它使我们能够创建存储外部提供给我们的值的属性。用户处于正常白天模式还是暗黑模式?他们是否要求较小或较大的字体?他们在哪个时区?所有这些以及更多都是来自环境的值,在这种情况下,我们将从环境中读取视图的演示模式。

视图的呈现模式仅包含两个数据,但两者都很有用:一个用于存储视图当前是否显示在屏幕上的属性,以及一种让我们立即关闭视图的方法。

要进行尝试,请将此属性添加到SecondView中,该视图将创建一个名为presentationMode的属性,该属性附加到存储在应用程序环境中的演示模式变量中:

@Environment(\.presentationMode) var presentationMode

现在,用此按钮替换SecondView中的文本视图:

Button("Dismiss") {
    self.presentationMode.wrappedValue.dismiss()
}

需要在其中添加wrapdValue,因为presentationMode实际上是一个绑定,因此它可以由系统自动更新——我们需要在其中进行解包以检索实际的呈现方式,以关闭视图。

无论如何,有了该按钮,您现在应该可以通过按按钮显示和隐藏工作表。

译自 Showing and hiding views

SwiftUI:使用@ObservedObject共享状态 Hacking with iOS: SwiftUI Edition SwiftUI:使用onDelete() 删除项目

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:Sheet 视图)