前言:
而今你们对“ios常用数据结构与算法”可能比较珍视,我们都需要剖析一些“ios常用数据结构与算法”的相关知识。那么小编同时在网摘上搜集了一些关于“ios常用数据结构与算法””的相关知识,希望你们能喜欢,看官们一起来了解一下吧!在前面的文章中,我们学习了如何实现IOS的界面布局以及IOS中的数据类型的概念,今天我们通过一个小示例来使用界面布局以及数据类型。
示例需求描述
实现一个用户列表,点击列表中的每一项后,可以跳转到用户详情信息页。
界面布局
定义用户信息类型
第一步:右键工程目录-> new Group,命名为model
第二步:创建UserInfo数据类型,右键工程目录->New File, 选择Swift File,命名为UserInfo
第三步:定义UserInfo数据结构
上篇文章中,我们学习过如何定义数据结构,这里我们实际练习一下。编写UserInfo,作为一个struct类型,UserInfo定义如下:
import Foundationstruct 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 Foundationvar 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 SwiftUIstruct 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 SwiftUIimport MapKitstruct 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 SwiftUIstruct 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 SwiftUIstruct 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 Foundationstruct 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 SwiftUIstruct 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,其中:
@State是一个状态装饰器,用于标识View中的一个属性,用@State标识的属性可在界面组件中使用,如果用户输入了新的内容,则会修改該属性,如果该属性的值发生了变化,界面也会刷新,例如:
TextField("输入姓名", text: $name)@Environment这个修饰器是针对全局环境的,可从全局环境中获取变量,比如:
@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 SwiftUIstruct 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语言基础数据类型
标签: #ios常用数据结构与算法