SwiftUI极简教程29:Combine异步编程框架和MVVM开发模式的使用(上)

简介: SwiftUI极简教程29:Combine异步编程框架和MVVM开发模式的使用(上)

在本章中,你将学会如何使用Combine异步编程框架和MVVM开发模式完成一个登录注册页面及其逻辑交互。

image.png

在几乎所有App中,都需要一个用户注册登录页面,用来获取和绑定用户信息。用户量,特别是付费用户量,决定这一款产品能否成为爆款商品。

因此,做好注册登录页面是非要有必要的。

那么,我们开始吧。


项目创建


首先,创建一个新项目,命名为SwiftUIRegistration

image.png

主要页面绘制


我们简单分析下页面组成,它由一个用户名称输入框、一个密码输入框、一个密码二次确认输入框组成。

image.png

首先是用户名称输入框,它是一个简答的TextField输入框,我们只需要使用@State初始化存储一个String类型的参数,绑定就可以了。


//用户名
TextField("用户名", text: $username)
    .font(.system(size: 20, weight: .semibold)) 
    .padding(.horizontal)


然后是密码输入框,它有点不同,在SwiftUI中,除了TextField输入框外,还有一种密码类型的输入框SecureField,使用方法和TextField输入框类似。


//密码
SecureField("密码", text: $password)
    .font(.system(size: 20, weight: .semibold)) 
    .padding(.horizontal)


密码二次确认输入框也是同样是SecureField密码输入框,为了隔开内容,输入框都可以使用Divider分割线分开,这样美观一些。


//分割线
Divider()
    .frame(height: 1)
    .background(Color(red: 240/255, green: 240/255, blue: 240/255))
    .padding(.horizontal)


最后是注册按钮,按照之前的章节,我们放一个简单的按钮。


//注册按钮
Button(action: {
    }) {
    Text("注册")
        .font(.system(.body, design: .rounded))
        .foregroundColor(.white)
        .bold()
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity)
        .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255))
        .cornerRadius(10)
        .padding(.horizontal)
    }


我们准备好这些元素后,将他们用VStack纵向排布在一起。

image.png

代码优化


我们发现,相同的代码太多了,这不够优雅。

哪怕是做任何项目,我们编程都力求优雅。我们可以把相同的内容抽离出来,除了样式外,我们发现TextField输入框和SecureField密码输入框除了类型不一样,其他都是一样的。

那么我们可以通过一个判断来抽离主体内容。


//注册视图
struct RegistrationView:View {
    var isTextField = false
    var fieldName = ""
    @Binding var fieldValue: String
    var body: some View {
        VStack {
            //判断是不是输入框
            if isTextField {
                //输入框
                TextField(fieldName, text: $fieldValue)                 
                    .font(.system(size: 20, weight: .semibold))
                    .padding(.horizontal)
            } else {
                //密码输入框
                SecureField(fieldName, text: $fieldValue)
                    .font(.system(size: 20, weight: .semibold))
                    .padding(.horizontal)
            }
            //分割线
            Divider()
                .frame(height: 1)
                .background(Color(red: 240/255, green: 240/255, blue: 240/255))
                .padding(.horizontal)
        }
    }
}


然后,我们只需要在ContentView主视图中引用并绑定就完成了页面设计。


RegistrationView(isTextField: true, fieldName: "用户名", fieldValue: $username)
RegistrationView(isTextField: false, fieldName: "密码", fieldValue: $password)
RegistrationView(isTextField: false, fieldName: "再次输入密码", fieldValue: $passwordCon


image.png

报错信息绘制

然后,我们来实现了报错信息提醒。

image.png

同理,我们也把相同元素抽离出来,我们可以看到如果校验不通过,它会展示一个Image图标和错误信息Text文字,逻辑我们先放一边,完成页面。


//错误信息
struct InputErrorView:View {
    var iconName = ""
    var text = ""
    var body: some View {
        HStack {
            Image(systemName: iconName)
                .foregroundColor(Color(red: 251/255, green: 128/255, blue: 128/255))
            Text(text)
                .font(.system(.body, design: .rounded))
                .foregroundColor(Color(red: 251/255, green: 128/255, blue: 128/255))
            Spacer()
        }.padding(.leading,10)
    }
}


然后在ContentView主视图中引用并绑定,效果如下:

image.png

恭喜你,完成了本章页面的设计编程。

由于这一章的内容有点多,那么我们也将分章节写完,不要着急。

下一章,我们将基于这个注册登录页面学习Combine异步编程框架的使用。


完整代码


import SwiftUI
struct ContentView: View {
    @State private var username = ""
    @State private var password = ""
    @State private var passwordConfirm = ""
    var body: some View {
        VStack (alignment: .leading, spacing: 40) {
            //用户名
            VStack {
                RegistrationView(isTextField: true, fieldName: "用户名", fieldValue: $username)
                InputErrorView(iconName: "exclamationmark.circle.fill", text: "用户不存在")
            }
            //密码
            VStack{
                RegistrationView(isTextField: false, fieldName: "密码", fieldValue: $password)
                InputErrorView(iconName: "exclamationmark.circle.fill", text: "密码不正确")
            }
            //再次输入密码
            VStack {
                RegistrationView(isTextField: false, fieldName: "再次输入密码", fieldValue: $passwordConfirm)
                InputErrorView(iconName: "exclamationmark.circle.fill", text: "两次密码需要相同")
            }
            //注册按钮
            Button(action: {
            }) {
                Text("注册")
                    .font(.system(.body, design: .rounded))
                    .foregroundColor(.white)
                    .bold()
                    .padding()
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255))
                    .cornerRadius(10)
                    .padding(.horizontal)
            }
        }.padding()
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
//注册视图
struct RegistrationView:View {
    var isTextField = false
    var fieldName = ""
    @Binding var fieldValue: String
    var body: some View {
        VStack {
            //判断是不是输入框
            if isTextField {
                //输入框
                TextField(fieldName, text: $fieldValue)
                    .font(.system(size: 20, weight: .semibold))
                    .padding(.horizontal)
            } else {
                //密码输入框
                SecureField(fieldName, text: $fieldValue)
                    .font(.system(size: 20, weight: .semibold))
                    .padding(.horizontal)
            }
            //分割线
            Divider()
                .frame(height: 1)
                .background(Color(red: 240/255, green: 240/255, blue: 240/255))
                .padding(.horizontal)
        }
    }
}
//错误判断
struct InputErrorView:View {
    var iconName = ""
    var text = ""
    var body: some View {
        HStack {
            Image(systemName: iconName)
                .foregroundColor(Color(red: 251/255, green: 128/255, blue: 128/255))
            Text(text)
                .font(.system(.body, design: .rounded))
                .foregroundColor(Color(red: 251/255, green: 128/255, blue: 128/255))
            Spacer()
        }.padding(.leading,10)
    }
}


快来动手试试吧!


相关文章
|
2月前
|
iOS开发 开发者 UED
探索iOS应用开发中的SwiftUI框架
【9月更文挑战第26天】 在iOS开发的海洋中,SwiftUI犹如一艘现代的快艇,引领着开发者们驶向更加高效与直观的编程体验。本文将带你领略SwiftUI的魅力,从其设计理念到实际应用,我们将一步步揭开它如何简化界面构建过程的面纱。通过对比传统方式,你将看到SwiftUI如何让代码变得像诗一样优美,同时保持强大的功能性和灵活性。准备好让你的iOS开发技能加速升级,一起驾驭这股新潮流吧!
|
6月前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
前端开发
MVVM框架原理
MVVM框架(Model-View-ViewModel)是一种基于数据绑定的前端架构模式。它将视图逻辑与业务逻辑分离,提供了一种简单而清晰的方式来管理和组织代码。
468 0
|
前端开发 开发者 UED
前端封装库/工具库的UI框架之Semantic UI
随着前端技术的不断发展,前端开发也越来越受到了重视。而在前端开发过程中,UI框架是不可或缺的一部分。Semantic UI 是一个流行的、现代化的 UI 框架,它为前端开发者提供了一套丰富、易用的组件库和样式表。
449 0
|
存储 前端开发 数据安全/隐私保护
SwiftUI极简教程31:Combine异步编程框架和MVVM开发模式的使用(下)
SwiftUI极简教程31:Combine异步编程框架和MVVM开发模式的使用(下)
1060 0
SwiftUI极简教程31:Combine异步编程框架和MVVM开发模式的使用(下)
|
前端开发 数据处理 API
SwiftUI极简教程30:Combine异步编程框架和MVVM开发模式的使用(中)
SwiftUI极简教程30:Combine异步编程框架和MVVM开发模式的使用(中)
931 0
SwiftUI极简教程30:Combine异步编程框架和MVVM开发模式的使用(中)
|
iOS开发
SwiftUI极简教程06:代码优雅复用
SwiftUI极简教程06:代码优雅复用
493 0
SwiftUI极简教程06:代码优雅复用
|
XML 存储 ARouter
MVVM框架初探
MVVM框架初探
312 0
MVVM框架初探
|
前端开发
[译] 实用的 MVVM 和 RxSwift
今天我们将使用 RxSwift 实现 MVVM 设计模式。对于那些刚接触 RxSwift 的人,我 在这里 专门做了一个部分来介绍。
1365 0
|
前端开发 架构师 程序员
【我们一起写框架】MVVM的WPF框架(一)—序篇
前言我想,有一部分程序员应该是在二三线城市的,虽然不知道占比,但想来应该不在少数。 我是这部分人群中的一份子。 我们这群人,面对的客户,大多是国内中小企业,或者政府的小部门。这类客户的特点是,资金有限,人力有限。
1560 0