大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。
在前面的文章中,我们学习了如何实现IOS的界面布局以及IOS中的数据类型的概念,今天我们通过一个小示例来使用界面布局以及数据类型。
实现一个用户列表,点击列表中的每一项后,可以跳转到用户详情信息页。
定义用户信息类型
第一步:右键工程目录-> new Group,命名为model
第二步:创建UserInfo数据类型,右键工程目录->New File, 选择Swift File,命名为UserInfo
第三步:定义UserInfo数据结构
上篇文章中,我们学习过如何定义数据结构,这里我们实际练习一下。编写UserInfo,作为一个struct类型,UserInfo定义如下:
import Foundation
struct UserInfo: Identifiable {
/**
* user id
*/
var id: Int
/**
* user name
*/
var name: String
/**
* 地址
*/
var address: String
/**
* 用户电话
*/
var phone: String
}
Identifiable是IOS sdk中定义的协议,UserInfo: Identifiable表示UserInfo这个结构体实现了Identifiable协议,该协议表示UserInfo中通过id字段标识UserInfo实例的唯一性
定义好UserInfo数据类型后,我们创建几个UserInfo对象:
在UserInfo.swift文件中,我们创建UserInfo数组,最终UserInfo.swift中的代码如下:
import Foundation
var userInfos = [
UserInfo(id: 1, name: "张三", address: "北京市昌平区某街道", phone: "133****1234"),
UserInfo(id: 2, name: "李四", address: "北京市海淀区某街道", phone: "133****2234"),
UserInfo(id: 3, name: "王麻子", address: "北京市朝阳区某街道", phone: "133****3234"),
UserInfo(id: 4, name: "赵八", address: "北京市海淀区某街道某小区xx号楼", phone: "133****4234")
]
struct UserInfo: Identifiable {
/**
* user id
*/
var id: Int
/**
* user name
*/
var name: String
/**
* 地址
*/
var address: String
/**
* 用户电话
*/
var phone: String
}
这里我们定义了4个UserInfo实例。
创建用户列表
在定义了用户信息数据后,我们接下来学习如何创建界面
第一步:创建一个SwiftUI View,命名为UserList
第二步:在UserList中创建Navigation View
在UserList中展示上文中的用户信息列表:代码如下:
import SwiftUI
struct UserList: View {
var body: some View {
NavigationView {
List(userInfos) { u in
NavigationLink {
} label: {
HStack {
Text(u.name)
}
}
}
}
.navigationTitle("用户列表")
}
}
struct UserList_Previews: PreviewProvider {
static var previews: some View {
UserList()
}
}
界面效果:
接下来,我们修改ContentView,在其中加入UserList,如下:
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
TabView(selection: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Selection@*/.constant(1)/*@END_MENU_TOKEN@*/) {
UserList()
.tabItem { Text("主页") }.tag(1)
MapView(coordinate: CLLocationCoordinate2D(latitude: 40.22077, longitude: 116.23128))
.tabItem { Text("位置") }.tag(2)
Text("").tabItem { Text("我的") }.tag(3)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
主界面效果:
创建用户详情页
前面已定义好了用户列表,是一个导航列表页,但是点击列表页上的用户后,跳转的页面是全白的,毫无内容,如下:
那么如何添加用户详情呢?咱们一步步的学习。
第一步:创建UserDetail视图,右键工程目录->new file -> SwiftUI View,命名为UserDetail,并在UserDetail中定义变量userInfo,其类型为UserInfo,我们通过VStack、HStack和Text来展示用户信息,代码如下:
import SwiftUI
struct UserDetail: View {
var userInfo: UserInfo
var body: some View {
VStack {
HStack {
Text("姓名:")
Text(userInfo.name)
}
HStack {
Text("地址:")
Text(userInfo.address)
}
HStack {
Text("电话:")
Text(userInfo.phone)
}
Spacer()
}
}
}
第二步:将UserDetail加入用户列表中,打开UserList.swift,在NavigationLink中加入UserDetail即可:
import SwiftUI
struct UserList: View {
var body: some View {
NavigationView {
List(userInfos) { u in
NavigationLink {
UserDetail(userInfo: u)
} label: {
HStack {
Text(u.name)
}
}
}
}
.navigationTitle("用户列表")
}
}
struct UserList_Previews: PreviewProvider {
static var previews: some View {
UserList()
}
}
有了这一步后,点击列表页,即可展示用户详情数据:
前文展示了用户信息的展示,接下来我们通过添加用户功能来学习如何获取界面上的数据输入。
修改模型
为了刷新列表页的用户数据,我们修改UserInfo.swift的内容如下:
import Foundation
struct UserInfo: Identifiable {
/**
* user id
*/
var id: Int
/**
* user name
*/
var name: String
/**
* 地址
*/
var address: String
/**
* 用户电话
*/
var phone: String
}
class UserWrapper: ObservableObject {
@Published var userInfos = [
UserInfo(id: 1, name: "张三", address: "北京市昌平区某街道", phone: "133****1234"),
UserInfo(id: 2, name: "李四", address: "北京市海淀区某街道", phone: "133****2234"),
UserInfo(id: 3, name: "王麻子", address: "北京市朝阳区某街道", phone: "133****3234"),
UserInfo(id: 4, name: "赵八", address: "北京市海淀区某街道某小区xx号楼", phone: "133****4234")
]
}
这里将原来的userInfos数组替换成了UserWrapper类,这个类继承自ObservableObject,其中包含一个userInfos且该属性被标识为@Published,我们的目的是想让userInfos发生变化时,用户列表也会跟着变化,
创建输入用户信息界面
同样,通过New File -> SwiftUI View创建文件,命名为CreateUserInfo,并使用TextField创建添加用户信息的界面元素:
import SwiftUI
struct CreateUserInfo: View {
var users: UserWrapper
@State var id: String = ""
@State var name: String = ""
@State var address: String = ""
@State var phone: String = ""
/**
* 用于操作当前界面,点击添加按钮添加用户后,将当前页面隐藏
*/
@Environment(\.presentationMode) var mode
init(users: UserWrapper) {
self.users = users
}
var body: some View {
Form {
VStack {
HStack {
Text("ID:")
TextField("输入ID", text: $id)
}
HStack {
Text("姓名:")
TextField("输入电话", text: $name)
}
HStack {
Text("地址:")
TextField("输入地址", text: $address)
}
HStack {
Text("电话:")
TextField("输入电话", text: $phone)
}
HStack {
Button("添加") {
var u = UserInfo(id: Int(id) ?? 0, name: name, address: address, phone: phone)
// let userInfos = [u]
users.userInfos.append(u)
self.mode.wrappedValue.dismiss()
}
}
}
}
}
}
这里需要解释一下,@State和@Environment以及@ObservedObject是swiftui为开发者提供的两个Attribute,其中:
TextField("输入姓名", text: $name)
@Environment(\.presentationMode) var mode
可用于控制当前界面是否显示
在咱们这个添加用户信息的界面代码中,还有一个按钮处理:
Button("添加") {
let u = UserInfo(id: Int(id) ?? 0, name: name, address: address, phone: phone)
userInfos.append(u)
self.mode.wrappedValue.dismiss()
}
这里将文本框中的ID、姓名、地址和电话创建一个UserInfo对象,并添加到userInfos中
将创建用户页入口添加到用户列表
打开UserInfoList.swift,将NavigationView中的List视图修改为如下代码:
import SwiftUI
struct UserList: View {
@StateObject var users = UserWrapper()
var body: some View {
NavigationView {
List {
NavigationLink {
CreateUserInfo(users: users)
} label: {
Text("添加")
}
ForEach(users.userInfos) { u in
NavigationLink {
UserDetail(userInfo: u)
} label: {
HStack {
Text(u.name)
}
}
}
}
}
.navigationTitle("用户列表")
}
}
struct UserList_Previews: PreviewProvider {
static var previews: some View {
UserList()
}
}
在新的代码中,我们通过users.userInfos创建用户信息列表,注意,users被@StateObject标识,表示该对象的属性变化后会自动重新刷新View。
运行结果如下:
初始时的用户列表:
点击添加创建一个新的用户:
输入用户信息点击添加后的用户列表:
点击刚添加的用户进入用户详情页:
本次我们使用的数据都是本地未经过存储的,我们的目的在于学习如何获取用户的输入并处理数据,最后把新的数据展示出来,后面的文章我们再来学习如何从指定文件或者远程服务上获取数据。
往期文章回顾:
新手学IOS开发-开发环境搭建
新手学IOS开发-APP界面布局基础开发
新手学IOS开发-swift语言基础数据类型