实战编程·使用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月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
239 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
205 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
5月前
|
容器
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
|
1月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
524 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
122 0
|
4月前
|
缓存 小程序 视频直播
基于uni-app+vite5+vue3实战短视频+直播+聊天app应用
基于uniapp+vue3+vite5从0-1实战搭建仿抖音/微信直播带货商城。集短视频+聊天+直播功能于一体。实现全屏沉浸式切换短视频/直播,支持编译运行到h5+小程序端+app端。
352 4
|
4月前
|
存储 移动开发 监控
App Trace功能实战:一键拉起、快速安装与免提写邀请码的应用实践
App Trace系统通过一键拉起、快速安装和免提写邀请码三大功能,显著提升用户转化率、安装成功率和邀请注册率。结合深度技术实现与优化,助力公司用户增长,成为移动端核心基础设施。
|
1月前
|
缓存 移动开发 JavaScript
如何优化UniApp开发的App的启动速度?
如何优化UniApp开发的App的启动速度?
422 139
|
1月前
|
移动开发 JavaScript weex
UniApp开发的App在启动速度方面有哪些优势和劣势?
UniApp开发的App在启动速度方面有哪些优势和劣势?
298 137
下一篇
oss云网关配置