实战编程·使用SwiftUI从0到1完成一款iOS笔记App(三)(2)

简介: 实战编程·使用SwiftUI从0到1完成一款iOS笔记App(三)

@Binding属性包装器

这里科普下@State@Binding的用法,@State属性包装器常常用于声明变量的前缀,使用@State属性包装器声明的变量,可以存储当前参数的状态或者值,而@Binding属性包装器常常在其他页面反向绑定@State属性包装器声明的变量。

比如,在首页声明的打开弹窗的参数showNewNoteView,在首页切换showNewNoteView状态用于打开弹窗,因此需要存储其状态

而在新建笔记页面需要关闭弹窗,而开启和关闭弹窗的参数在首页中,于是需要使用@Binding属性包装器进行两个页面之间的双向绑定。

于是使用@Binding声明的showNewNoteView参数在新建笔记切换其状态,在首页中@State声明绑定的同一个参数就可以实时监听更新其状态,就实现了关闭弹窗的交互。

好了,回归主题,我们这里需要修改的将NoteListView笔记列表视图的NoteItem模型类数组使用@Binding进行双向绑定,并在ContentView首页视图中进行绑定,如下代码所示:

@Binding var noteItems: [NoteItem]

image.png

运行预览效果如下图所示:

image.png

提示信息

新建笔记时,当“新建笔记”页面标题输入框为空,以及“内容输入框”为空时,点击“完成”按钮,应用会创建一条空白的笔记,如下图所示:

image.png

这不是我们想要的结果。

新建笔记页面标题、内容输入框都必须输入内容,方可点击创建一条新笔记,当不满足此条件时,则需要提示用户相应的内容,告知用户需要填写和输入。

在移动端常见的方式是使用Toast冒泡提示,我们可以使用ViewModifier协议创建一个Toast视图,首先创建一个新的Swift文件,命名为ToastView

然后录入下面的代码:


import SwiftUI
struct ToastViewModifier: ViewModifier {
    @Binding var present: Bool
    @Binding var message: String
    var alignment: Alignment = .center
    func body(content: Content) -> some View {
        ZStack {
            content
                .zIndex(0)
            VStack {
                Text(message)
                    .padding(Edge.Set.horizontal, 20)
                    .padding(Edge.Set.vertical, 10)
                    .multilineTextAlignment(.center)
                    .foregroundColor(.white)
                    .background(Color.black.opacity(0.7))
                    .cornerRadius(5)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: alignment)
            .background(Color.gray.opacity(0.1))
            .opacity(present ? 1 : 0)
            .zIndex(1)
            .onChange(of: present) { value in
                if value {
                    // 延迟2秒消失
                    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                        present.toggle()
                    }
                }
            }
        }
    }
}
extension View {
    func toast(present: Binding<Bool>, message: Binding<String>, alignment: Alignment = .center) -> some View {
        modifier(ToastViewModifier(present: present, message: message, alignment: alignment))
    }
}

image.png

上述代码中,我们实现了一个Toast冒泡提示的样式,详细说明见【Swift实用小册19:ExtenExtension扩展的使用】。

回到NewNoteView新建笔记视图,我们先声明Toast需要的参数,如下代码所示:

less

复制代码

@State var showToast = false
@State var showToastMessage: String = ""

上述代码中,showToast参数触发是否展示Toast,showToastMessage参数则显示Toast的内容。调用Toast的方法如下代码所示:

php

复制代码

.toast(present: $showToast, message: $showToastMessage, alignment: .center)

回到逻辑部分,我们需要判断输入的标题title、内容content是否为空,若为空,则展示相应的内容,我们可以写一个方法判读输入内容是否为空,如下代码所示:

arduino

复制代码

// MARK: 判断输入是否为空
func isNull(text: String) -> Bool {
    if text == "" {
        return true
    }
    return false
}

上述代码中,我们创建了一个判断输入的文字是否为空的方法isNull,传入一个String类型的文字,通过判断是否为空,对应返回Bool

我们在点击“完成”按钮时,调用判断方法,如下代码所示:

if isNull(text: title) {
  self.showToastMessage = "请输入标题"
  self.showToast = true
} else if isNull(text: content) {
  self.showToastMessage = "请输入内容"
  self.showToast = true
} else {
  addNote(writeTime: getCurrentTime(), title: title, content: content)
  self.showNewNoteView = false
}

本章项目预览

完成后,我们回到ContentView首页,运行预览效果如下图所示:

本章小结

在本章中,我们实现了新建笔记的方法,当然也传达了一个很重要的编程理念,也就是结构化编程

无论是View视图,还是实现某种功能的方法,我们编程的方式都是抽离出来单独构建。这样编程的好处是当我们需要修改某块内容样式或者逻辑时,可以快速定位到相关的内容,并且尽量使得视图、方法松散分离,变成一块一块的代码块,便于后期扩充

这也是我喜欢SwiftUI的地方,也是喜欢写代码的原因。

接下来的章节,我们将继续完成交互逻辑部分,请保持期待吧~

相关文章
|
1月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
92 3
|
1月前
|
iOS开发 开发者
一键制作 iOS 上架 App Store 描述文件教程
一键制作 iOS 上架 App Store 描述文件教程
|
1月前
|
Android开发 iOS开发 开发者
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
103 0
|
1月前
|
iOS开发
iOS自动混淆测试处理笔记
iOS自动混淆测试处理笔记
12 0
|
1月前
|
开发者 iOS开发
iOS App上架新规解析:如何进行App备案
iOS App上架新规解析:如何进行App备案
151 0
|
1月前
|
iOS开发 开发者
【教程】uni-app iOS 打包解决 profile 文件与私钥证书不匹配问题
【教程】uni-app iOS 打包解决 profile 文件与私钥证书不匹配问题
|
1月前
|
Android开发 开发者 UED
个人开发 App 成功上架手机应用市场的关键步骤
个人开发 App 成功上架手机应用市场的关键步骤
|
1月前
|
开发工具 数据安全/隐私保护 Android开发
【教程】APP 开发后如何上架?
【教程】APP 开发后如何上架?
|
1月前
|
API
uni-app 146朋友圈列表api开发
uni-app 146朋友圈列表api开发
19 0
|
1月前
|
Java Android开发 开发者
【Uniapp开发】APP的真机调试指南,从开发到上架全过程
【Uniapp开发】APP的真机调试指南,从开发到上架全过程
36 3