本文将介绍SwiftUI中常见的几种页面跳转的方法。
TabView 提供了适合平台的标签页切换 UI,使用交互用户界面元素在多个子视图之间切换的视图。其中的每个子视图就是 TabView 的便签页的内容。
导航视图非常适合让我们创建视图的分层堆栈,以使用户能够向下钻取数据,但是它们对于显示无关数据的效果不佳。为此,我们需要使用SwiftUI的TabView,它会在屏幕底部创建一个按钮条,点击每个按钮会显示一个不同的视图。
TabView的功能非常强大,更多关于TabView的使用场景可以参考:http://www.55mx.com/tag/238.html
1、基本使用
要创建带有选项卡的用户界面,请在TabView中放置视图,并对每个选项卡的内容应用tabItem(_:)修饰符。但是,实际上,您始终希望自定义选项卡的显示方式-在选项卡栏上方的代码中将有一个空白的空白空间。
尽管您可以点击该灰色空间的左右部分来激活两个选项卡,但这是非常糟糕的用户体验。 相反,最好将tabItem()修饰符附加到内的每个视图TabView。这使您可以自定义视图在选项卡栏中的显示方式,从而在其旁边提供图像和一些文本, 下面创建一个有三个选项卡的选项卡视图:
TabView {
Text("第一个标签页")
// .tabItem 是每个标签页的图标。
// 不附上 .tabItem 的话,图标会为空,但是点击对应位置仍然可以实现跳转
.tabItem {
Image(systemName: "1.square.fill")
Text("第一")
}
Text("又一个标签页")
.tabItem {
Image(systemName: "2.square.fill")
Text("第二")
}
Text("最后一个标签页")
.tabItem {
Image(systemName: "3.square.fill")
Text("第三")
}
}
.font(.headline)
tabItem是设置此视图的唯一标记值。使用tabItem(_:)将视图配置为TabView中的标签栏项。上面的例子在TabView中添加了三个视图作为标签。
2、通过tag识别当前所在页
tag是一种设置此视图的唯一标记值。我们先绑定一个可以传值的属性:
@State var selection = 0
然后我们就可以通过TabView(selection: $selection) 方式识别当前页的值;
VStack {
// TabView 可以用和 Picker 类似的方式获取当前在哪个标签页
Text("目前在第 (selection + 1) 个标签页")
TabView(selection: $selection) {
Text("第一个标签页")
.tabItem {
Image(systemName: "1.square.fill")
Text("第一")
}
// 获取的前提是给每个 tablItem 都加上 tag
.tag(0)
Text("又一个标签页")
.tabItem {
Image(systemName: "2.square.fill")
Text("第二")
}
.tag(1)
Text("最后一个标签页")
.tabItem {
Image(systemName: "3.square.fill")
Text("第三")
}
.tag(2)
}
.font(.headline)
}
使用tag(_:)来区分多个视图,以便选择像选择器和列表这样的控件。标签值可以是符合可哈希协议的任何类型。
在下面的例子中,Picker视图生成器中的ForEach循环将遍历Flavor枚举。它提取每个枚举元素的文本原始值,作为行项标签使用,并使用枚举项本身作为标记(_:)修饰符的输入。标签标识符可以是符合哈希(Hashable)协议的任何值。
3、使用onTapGesture跳转到指定页面:
只在上面的代码中稍加修改就可以实现点击某个绑定了onTapGesture区域的页面跳转功能。
Text("目前在第 (selection + 1) 个标签页")
TabView(selection: $selection) {
Text("点我跳转到第三页(当前是第一页)")
.onTapGesture {
self.selection = 2
}
.tabItem {
Image(systemName: "1.square.fill")
Text("第一页")
}
// 获取的前提是给每个 tablItem 都加上 tag
.tag(0)
Text("点我跳转到第一页(当前是第二页)")
.onTapGesture {
self.selection = 0
}
.tabItem {
Image(systemName: "2.square.fill")
Text("第二页")
}
.tag(1)
Text("点我跳转到第二页当前是第三页)")
.onTapGesture {
self.selection = 1
}
.tabItem {
Image(systemName: "3.square.fill")
Text("第三页")
}
.tag(2)
}
NavigationLink是一种视图,用来表示导航层次结构中一个可见路径的视图堆栈。
NavigationView在视图的顶部显示了一个导航栏,但它还执行其他操作:它使我们可以将视图推入视图堆栈。实际上,这实际上是iOS导航的最基本形式-点击Wi-Fi或常规时,您可以在“设置”中看到它;或者点击某人的名字,则可以在“消息”中看到它。
该视图堆栈系统与我们下面将使用的 sheet 非常不同。两者都显示出某种新的特点,但是它们的呈现方式存在差异,这会影响用户对它们的思考方式。
1、基本使用
NavigationView {
VStack {
NavigationLink(destination: Text("点击后显示的视图内容")) {
Text("可点击内容")
}
}
.navigationBarTitle("这是顶部标题")
}
NavigationLink 用于显示有关用户选择的详细信息。
sheet() 用于显示不相关的内容,例如设置或撰写窗口。
2、NavigationLink 列表
NavigationLink 负责控制导航页的点击跳转,其主要有两个参数:destination 是跳转的目的地;label 导航栏中对应格子的标签。
NavigationView {
List(0..<3) { i in
NavigationLink(
destination: Text("点击列表页后进入的页面 (i)")) {
Text("列表序号 (i)")
}
}
.navigationBarTitle("标题")
}
NavigationLink非常适合做文章/项目的列表页,点击后进入项目内部子视图。
其实很多时候我们把sheet页当成了一个提示页,除了提示我们还可以有好几种用法。
func sheet(isPresented: Binding, onDismiss: (() -> Void)? = nil, content: @escaping () -> Content) -> some View where Content : View
mport SwiftUI
struct ContentView:View {
var body: some View{
TestSheet()
}
}
struct TestSheet: View {
@State private var popoverIsShown = false
var body: some View {
Button("显示 Sheet") {
self.popoverIsShown = true
}
.sheet(isPresented: self.$popoverIsShown) {
RandomSheet(popoverIsShown: self.$popoverIsShown)
}
}
}
struct RandomSheet: View {
@Binding var popoverIsShown: Bool
var body: some View {
Button("关闭") { self.popoverIsShown = false }
}
}
关于sheet的应用示例:http://www.55mx.com/ios/109.html
SwiftUI使我们Alert能够使用一个或两个按钮来显示重要的公告,并sheet()在当前视图的顶部显示整个视图,但这也给了我们ActionSheet:另一种选择是Alert,我们可以添加许多按钮。
视觉上的警报和操作表有很大的不同:在iPhone上,警报显示在屏幕中央,必须通过选择一个按钮主动将其关闭,而操作表则从底部向上滑动,可以包含多个按钮,并且可以通过点按来关闭在“取消”上或通过点击操作表的外部。
除了其演示文稿和不同数量的按钮外,操作表和警报还具有许多功能。两者都是通过在视图层次结构上附加一个修饰符来创建的- alert()用于警报和actionSheet()操作表-两者都在条件为真时由SwiftUI自动显示,并且都使用相同类型的按钮,并且都具有一些内置的默认样式按钮:default(),cancel(),和destructive()。
为了演示所使用的操作表,我们首先需要一个可切换某种条件的基本视图。例如,这显示了一些文本,点击文本会更改一个布尔值:
Button("显示Sheet页") {
showingSheet = true//点击后改显示
}
.actionSheet(isPresented: $showingSheet) {
ActionSheet(
title: Text("你想在这个页面放点啥?弹出一个提示,还可以修改信息等操作"),
message: Text("如果要关闭此页只需要向下滑动或者点击下面的按钮..."),
buttons: [.default(Text("关闭此面"))]
)
}
可以看出上面的buttons是一个数组,我们可以加入多个按钮:
.actionSheet(isPresented: $showingActionSheet) {
ActionSheet(title: Text("Change background"), message: Text("Select a new color"), buttons: [
.default(Text("Red")) { self.backgroundColor = .red },
.default(Text("Green")) { self.backgroundColor = .green },
.default(Text("Blue")) { self.backgroundColor = .blue },
.cancel()
])
}
五、popover
popover是一个专用的修改器来显示弹出窗口,在iPadOS上它显示为浮动气球,而在iOS上则像一张纸一样滑到屏幕上。
要显示弹出窗口,您需要某种状态来确定该弹出窗口当前是否可见,但仅此而已–与警报和操作表不同,弹出窗口可以包含所需的任何视图。因此,只要将您需要的任何东西放在弹出窗口中,SwiftUI就会处理其余的工作。
例如,当点击一个按钮时,将显示一个弹出视图:
struct ContentView: View {
@State private var showingPopover = false
var body: some View {
Button("显示菜单") {
showingPopover = true
}
.popover(isPresented: $showingPopover) {
Text("你要的内容在这里!")
.font(.headline)
.padding()
}
}
}
isPresented 是否显示弹出窗口的绑定。
attachmentAnchor 定位锚,它定义了弹出窗口的附加位置。
arrowEdge 弹出窗口箭头所在的attachmentAnchor的边缘。
content 返回弹出窗口内容的闭包。
如果发生重要事件,通知用户的常用方法是使用警报-alert,其中包含标题,消息和一个或两个按钮(取决于您的需要)。
但是请考虑一下:何时应该显示警报以及如何显示警报?视图是我们程序状态的函数,警报也不例外。因此,我们不用说“显示警报”,而是创建警报并设置显示警报的条件。
基本的SwiftUI警报具有标题,消息和一个关闭按钮,如下所示:
Alert(title: Text("弹出的标题!"), message: Text("这是消息的内容"), dismissButton: .default(Text("OK")))
如果需要,您可以添加更多代码以更详细地配置按钮,但这已经足够了。更有趣的是我们如何显示警报:我们不将警报分配给变量,而是编写类似之类的内容myAlert.show(),因为这将支持旧的“事件系列”思维方式。 相反,我们创建一些状态来跟踪我们的警报是否正在显示,如下所示:
@State private var showingAlert = false
然后,我们将警报附加到用户界面的某处,告诉它使用该状态来确定是否显示警报。SwiftUI将监视showingAlert,一旦变为true,它将显示警报。 将所有内容放在一起,下面是一些示例代码,这些代码在点击按钮时显示警报:
struct ContentView: View {
@State private var showingAlert = false
var body: some View {
Button("显示弹窗") {
self.showingAlert = true
}
.alert(isPresented: $showingAlert) {
Alert(title: Text("弹出标题!"), message: Text("弹出消息的内容"), dismissButton: .default(Text("OK")))
}
}
}
alert:提示框,最多两个按钮
.alert(isPresented: $showAlert){
Alert(title: Text("one"), message: Text("two"), dismissButton: .default(Text("ok")))
return Alert(title: Text("one"), message: Text("one"), primaryButton: .cancel(Text("取消"), action: {
print("取消")
}), secondaryButton:.default(Text("确定"), action: {
print("确定")
}))
}
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/127
《【SwiftUI基础篇】13 页面跳转的几种方式TabView、NavigationLink、sheet》的网友评论(0)