新手学IOS开发-数据展示与获取用户输入[通俗易懂]

Ios (75) 2023-03-24 21:31

大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。

在前面的文章中,我们学习了如何实现IOS的界面布局以及IOS中的数据类型的概念,今天我们通过一个小示例来使用界面布局以及数据类型。

示例需求描述

实现一个用户列表,点击列表中的每一项后,可以跳转到用户详情信息页。

界面布局

定义用户信息类型

第一步:右键工程目录-> new Group,命名为model

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第1张

new group

第二步:创建UserInfo数据类型,右键工程目录->New File, 选择Swift File,命名为UserInfo

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第2张

new file

第三步:定义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

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第3张

新建文件

第二步:在UserList中创建Navigation View

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第4张

创建NavigationView

在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()
    }
}

界面效果:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第5张

用户列表

接下来,我们修改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()
    }
}

主界面效果:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第6张

主界面

创建用户详情页

前面已定义好了用户列表,是一个导航列表页,但是点击列表页上的用户后,跳转的页面是全白的,毫无内容,如下:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第7张

那么如何添加用户详情呢?咱们一步步的学习。

第一步:创建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()
    }
}

有了这一步后,点击列表页,即可展示用户详情数据:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第8张

用户详情

获取界面数据输入

前文展示了用户信息的展示,接下来我们通过添加用户功能来学习如何获取界面上的数据输入。

修改模型

为了刷新列表页的用户数据,我们修改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,其中:

  1. @State是一个状态装饰器,用于标识View中的一个属性,用@State标识的属性可在界面组件中使用,如果用户输入了新的内容,则会修改該属性,如果该属性的值发生了变化,界面也会刷新,例如:
TextField("输入姓名", text: $name)
  1. @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 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开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第9张

用户列表

点击添加创建一个新的用户:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第10张

添加用户

输入用户信息点击添加后的用户列表:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第11张

用户信息列表

点击刚添加的用户进入用户详情页:

新手学IOS开发-数据展示与获取用户输入[通俗易懂]_https://bianchenghao6.com/blog_Ios_第12张

用户详情

结语

本次我们使用的数据都是本地未经过存储的,我们的目的在于学习如何获取用户的输入并处理数据,最后把新的数据展示出来,后面的文章我们再来学习如何从指定文件或者远程服务上获取数据。

往期文章回顾:

新手学IOS开发-开发环境搭建

新手学IOS开发-APP界面布局基础开发

新手学IOS开发-swift语言基础数据类型

发表回复