SwiftUI极简教程14:ModalView模态弹窗使用

简介: SwiftUI极简教程14:ModalView模态弹窗使用

在本章中,你将学会使用模态弹窗完成页面跳转、自定义返回。


在上一章中,我们学习了使用NavigationView导航栏进行页面的跳转,这是常见的页面跳转的一种方式。


而另一种打开新页面的方式在iPhone中也很常见,就是从底部向上弹出一个新页面。

image.png

我们可以看到,这个页面又不完全是“进入”了一个新页面,它允许用户向下滑动关闭页面,这无疑大大增强了用户体验。

这时候给用户的感觉就是没有“打断”或者“干扰”用户的操作,并且完成了用户想做的事情。

本章节将分成3个部分讲解。


1、基于模态弹窗的页面跳转;

2、模态弹窗的自定义返回;

3、Alerts警告弹窗;


好了,说了那么多,我们开始吧。


第一部分:基于模态弹窗的页面跳转


首先,我们先创建一个新项目,命名为SwiftUIModalView。

image.png


我们尝试下简单的模态弹窗的跳转。

比如,我们在第一个页面创建一个按钮,当我们点击这个按钮时,打开一个模态弹窗页面。

如何创建按钮,可以了解下之前的文章。

创建按钮的代码如下:


//按钮
Button(action: {
    // 点击按钮跳转打开模态弹窗
}) {
    // 按钮样式
    Text("打开模态弹窗")
        .font(.system(size: 14))
        .frame(minWidth: 0, maxWidth: .infinity)
        .padding()
        .foregroundColor(.white)
        .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255))
        .cornerRadius(5)
        .padding(.horizontal, 20)
}


image.png

然后,我们需要再创建一个新的页面,方便我们实现从第一个页面点击按钮,以模态弹窗的方式打开第二个页面。

这里,我们基于上一章的内容,创建一个页面叫做DetailView。

在DetailView我们就放个文字简单说明下。


// 详情页
struct DetailView: View {
    var body: some View {
        Text("这是一个新页面")
    }
}


image.png


接下来,我们实现下使用模态弹窗的跳转方法。


.sheet(isPresented: $showDetailView) { 
    //要跳转的页面
 }
复制代码


模态弹窗的方法很简单,使用.sheet修饰符。

isPresented是模态弹窗的触发条件,需要用$绑定一个操作,我们通常定义一个布尔值,它的初始状态为false。


@State var showDetailView = false
复制代码


当我们在第一个页面点击按钮时,按钮的操作就把这个布尔值变成true,那么就可以同时触发.sheet打开模态弹窗。

这里我们定义了一个叫做showDetailView的参数,它是bool类型,而且初始值为false。

当我们点击按钮时,showDetailView切换状态。


self.showDetailView.toggle()


image.png

我们点击模拟器上的Preview试下效果。

点击按钮后,我们可以看到系统打开了我们定义好的模态弹窗页面DetailView了。

完整代码如下:


import SwiftUI
struct ContentView: View {
    @State var showDetailView = false
    var body: some View {
        // 按钮
        Button(action: {
            // 点击按钮跳转打开模态弹窗
            self.showDetailView.toggle()
        }) {
            // 按钮样式
            Text("打开模态弹窗")
                .font(.system(size: 14))
                .frame(minWidth: 0, maxWidth: .infinity)
                .padding()
                .foregroundColor(.white)
                .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255))
                .cornerRadius(5)
                .padding(.horizontal, 20)
        }
        .sheet(isPresented: $showDetailView) {
            DetailView()
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
// 详情页
struct DetailView: View {
    var body: some View {
        Text("这是一个新页面")
    }
}


image.png

第二部分:模态弹窗的自定义返回


在DetailView页面里,我们可以通过向下拖动页面,实现关闭页面的效果。

我们也可以尝试给DetailView加上一个关闭按钮,当我们点击关闭按钮时,也关闭这个页面。

还记得上一章我们学习过的NavigationView导航栏吗?我们可以给DetailView内容加上导航,然后导航右边加一个按钮操作。


// 详情页
struct DetailView: View {
    var body: some View {
        NavigationView {
            //主体内容
            Text("这是一个新页面")
                .navigationBarItems(trailing: Button(action: {
                    // 点击按钮关闭弹窗
                }) {
                    Image(systemName: "chevron.down.circle.fill")
                        .foregroundColor(.gray)
                }
            )
        }
    }
}


image.png

好了,我们看到在DetailView导航栏右上角创建了一个新按钮。

那么接下来,我们要实现点击按钮,关闭弹窗。

这里我们有两种方法。


方法1:


和上一章NavigationView导航栏一样,创建一个环境变量:


@Environment(\.presentationMode) var presentationMode
复制代码


然后当我们点击按钮时,调用它的函数方法。


self.presentationMode.wrappedValue.dismiss()
复制代码


点击模拟器的Preview,我们发现实现了点击操作,关闭当前的模态弹窗页面。

完整代码如下:


// 详情页
struct DetailView: View {
    //定义环境变量
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        NavigationView {
            //主体内容
            Text("这是一个新页面")
                .navigationBarItems(trailing: Button(action: {
                    // 点击按钮关闭弹窗
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Image(systemName: "chevron.down.circle.fill")
                        .foregroundColor(.gray)
                }
            )
        }
    }
}


image.png

方法2:

也是之前的章节学习过 State状态和Binding绑定的使用。

我们可以在DetailView页面用@Binding绑定第一个页面创建的showDetailView布尔值。


//绑定参数
@Binding var showDetailView: Bool
复制代码


然后在DetailView页面,点击按钮操作时,将showDetailView的值切换。


self.showDetailView.toggle()
复制代码


最后在主页中.sheet跳转的目标页面绑定参数回来。


.sheet(isPresented: $showDetailView) {
    DetailView(showDetailView: $showDetailView)
}
复制代码


这样,我们也可以实现页面的返回操作。

DetailView页面完整代码如下:


// 详情页
struct DetailView: View {
    //绑定参数
    @Binding var showDetailView: Bool
    var body: some View {
        NavigationView {
            //主体内容
            Text("这是一个新页面")
                .navigationBarItems(trailing: Button(action: {
                    // 点击按钮关闭弹窗
                    self.showDetailView.toggle()
                }) {
                    Image(systemName: "chevron.down.circle.fill")
                        .foregroundColor(.gray)
                }
            )
        }
    }
}


image.png

那么两种方法有什么不同呢?

第一种方法简单来说,是“撤销”原有的操作。

而第二种绑定的方式,是反向传递参数值给到第一个页面。

两种方式各有好处,第二种方法的好处是如果第二个页面返回的时候需要带参数值回来,那么我们可以通过绑定的方式将DetailView的值给回到第一个页面。


第三部分:Alerts警告弹窗


在模态弹窗中,还有一种类型叫做Alerts警告弹窗,也属于模态弹窗的一种。

我们在App也经常见过它,当我们确定要付款时,或者触发到有风险的操作时,系统就会打开Alerts警告弹窗。

Alerts警告弹窗一种二次确认的弹窗,常用于系统风险提醒、是否立即执行等场景。

image.png


创建警告弹窗的方法和创建一般的模态弹窗方法一样,只是参数不一样。


.alert(isPresented: $showAlert) {
    //Alerts结构体
}


我们还是使用isPresented触发,我们定义一个变量showAlert的状态,初始状态是false。


@State var showAlert = false


与创建标准模态弹窗不同的是,.alert里面的内容是Alerts结构体,也就是标准的警告弹窗。

我们使用Alert结构体来创建警告弹窗。


Alert(title: Text("这是弹窗标题"), message: Text("这是弹窗的内容"), primaryButton: .default(Text("确定")), secondaryButton: .cancel(Text("取消")))


基本了解了警告弹窗的用法,让我们实操试试吧。

我们把DetailView页面的文字改成“打开警告弹窗”,然后把它变成按钮的形式。

以便于我们点击文字按钮,实现打开警告弹窗的效果。

//主体内容
    Button(action: {
        // 点击按钮打开警告弹窗
        }) {
            Text("打开警告弹窗")
        }

image.png

然后我们将警告弹窗的方法写到DetailView页面里面,方法和主页中.sheet的方法类似。

先定义一个变量showAlert,初始值为false,当按钮点击的时候,showAlert的状态切换。

在Text按钮外边(注意位置),使用.alert的创建一个警告弹窗,然后在警告弹窗内容里填充Alerts结构体代码。

这样就完成了Alerts警告弹窗的创建。

DetailView完整代码如下:


// 详情页
struct DetailView: View {
    // 绑定参数
    @Binding var showDetailView: Bool
    @State var showAlert = false
    var body: some View {
        NavigationView {
            // 主体内容
            Button(action: {
                // 点击按钮打开警告弹窗
                self.showAlert.toggle()
            }) {
                Text("打开警告弹窗")
            }
            .alert(isPresented: $showAlert) {
                //Alerts结构体
                Alert(title: Text("这是弹窗标题"), message: Text("这是弹窗的内容"), primaryButton: .default(Text("确定")), secondaryButton: .cancel(Text("取消")))
            }
            .navigationBarItems(trailing: Button(action: {
                // 点击按钮关闭弹窗
                self.showDetailView.toggle()
            }) {
                Image(systemName: "chevron.down.circle.fill")
                    .foregroundColor(.gray)
            }
            )
        }
    }
}

image.png

快来动手试试吧!

相关文章
|
iOS开发
SwiftUI极简教程13:NavigationView导航栏使用
SwiftUI极简教程13:NavigationView导航栏使用
2526 2
SwiftUI极简教程13:NavigationView导航栏使用
|
存储 iOS开发
SwiftUI极简教程17:Gestures手势的使用
SwiftUI极简教程17:Gestures手势的使用
1276 0
SwiftUI极简教程17:Gestures手势的使用
|
存储 Swift
SwiftUI极简教程41:使用Segment、LazyVGrid和ImagePicker构建一个Logo生成器
在本章中,你将学会使用Segment分段器、LazyVGrid垂直网格、ImagePicker图片选择器构建一个Logo生成器。 在上一章中,我们完善了SearchBar搜索栏、TabView底部导航,还有做了一个Loading加载动作。最近突然有个想法,如果把色卡和图片进行组合,这不就是一个简单的Logo了吗?我能不能做个Logo生成器? 说干就干,我们继续完成App的相关内容。
867 0
SwiftUI极简教程41:使用Segment、LazyVGrid和ImagePicker构建一个Logo生成器
|
程序员 索引
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
1436 0
SwiftUI极简教程18:SwipeCard卡片滑动效果的使用(上)
使用SwiftUI搭建一个简易书籍阅读App,做一个爱读书的人~
使用SwiftUI搭建一个简易书籍阅读App,做一个爱读书的人~
319 0
使用SwiftUI搭建一个简易书籍阅读App,做一个爱读书的人~
|
存储 监控 vr&ar
大师学SwiftUI第18章Part1 - 图片选择器和相机
如今,个人设备主要用于处理图片、视频和声音,苹果的设备也不例外。SwiftUI可以通过Image视图显示图片,但需要其它框架的支持来处理图片、在屏幕上展示视频或是播放声音。本章中我们将展示Apple所提供的这类工具。
566 1
颜值即正义,使用SwiftUI搭建版本更新弹窗
颜值即正义,使用SwiftUI搭建版本更新弹窗
355 0
|
程序员 Swift
谁说程序员不懂浪漫,教你使用SwiftUI搭建一个电子相册送给她吧~
谁说程序员不懂浪漫,教你使用SwiftUI搭建一个电子相册送给她吧~
365 0
展开&收起,使用SwiftUI搭建一个侧滑展开页面交互
展开&收起,使用SwiftUI搭建一个侧滑展开页面交互
480 0
|
iOS开发
SwiftUI极简教程08: Button按钮的使用
SwiftUI极简教程08: Button按钮的使用
1575 0
SwiftUI极简教程08: Button按钮的使用

热门文章

最新文章