SwiftUI(Sheet|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 = falsevar body: some View { Button("Show Sheet") { self.showingSheet.toggle() } .sheet(isPresented: $showingSheet) { SecondView() } } }

如果您现在运行该程序,则会看到您可以点击按钮,使第二个视图从底部向上滑动,然后将其向下拖动以将其关闭。
创建这样的视图时,可以传入需要工作的任何参数。例如,我们可以要求为SecondView发送一个可以显示的名称,如下所示:
struct SecondView: View { var name: Stringvar 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|SwiftUI:Sheet 视图)】赏我一个赞吧~~~

    推荐阅读