在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() 删除项目 |
---|
赏我一个赞吧~~~