条件回忆

在上两个章节中,咱们完结了个人主页以及增加身份卡页面的规划,其间学习怎么数据模型、列表创建卡片展现视图,以及打开页面和封闭页面的交互动作,在本章节中,咱们来学习建立增加身份卡页面的相关内容。

界面分析:页面元素及其优先级

增加身份卡页面,需求依据个人主页身份卡的内容来构建,身份卡对应展现的信息,就是咱们需求在新增时创建的信息,如下图所示:

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

关于信息的优先级,主要信息为渠道称谓,其次信息是渠道图标和渠道称谓,再次隐藏信息是链接地址。

确认页面元素的优先级需求遵循用户惯性逻辑以及运用想给用户出现的关键点,在身份卡中关于用户而言最中心的信息是在渠道所获得的称谓,而渠道称谓也是在个人主页身份卡中用户视线首要关注的内容。

其次的渠道信息部分,由渠道图标和渠道称谓组成,这是因为这两块信息具有相关性,渠道称谓对应着渠道图标,因而在产品规划上能够耦合在一起。

最终是链接地址部分,后续咱们希望关联对应渠道地址后,能点击身份卡片在运用内打开浏览器并拜访链接地址,而链接地址在整个身份卡片中是不展现其内容的,因而信息的优先级能够放置至最终。

变量声明:身份卡必要参数准备

分析完界面元素后,咱们在创建页面之前先确认好需求运用到的变量,如下代码所示:

@State var platformIcon: String = "icon_juejin"
@State var title: String = "移动端签约作者"
@State var platformName: String = "稀土技能社区"
@State var indexURL: String = "https:///user/3897092103223517"

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

上述代码中,咱们都运用@State进行变量的声明,@State能够存储声明的变量及其变量的值。而且为了出现作用,咱们给声明的参数都赋予了初始值。

界面规划:渠道称谓输入框

声明好需求的变量后,咱们来建立渠道称谓输入框内容,咱们能够和建立closeBtn封闭按钮视图相同,独自建立渠道输入框视图,再将该视图内容赋予NewView主要的视图中,如下代码所示:

// 头衔称谓输入框
func titleInputView() -> some View {
    TextField("请输入头衔", text: $title)
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(8)
        .padding(.horizontal)
}

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

上述代码中,咱们创建了一个渠道称谓输入框视图titleInputView,主体内容运用TextField输入框控件,输入框提示文字为“请输入头衔”,输入内容绑定声明的变量title。

在款式方面,为了突出输入框视图内容,运用padding修饰符“撑开”输入框外层区域,将外层区域填充背景色为systemGray6,并设置圆角度数为8,最终设置水平方位两边留白,便完结了上图作用。

界面规划:自定义渠道挑选器

接下来咱们来规划“挑选渠道”的操作逻辑。能够简单想象下,用户在“增加身份卡”页面输入完渠道称谓后,下一步是挑选该称谓地点的社区或者渠道。

最直观的展现方式是将渠道都摆放出来让用户进行挑选,而因为展现空间有限,咱们能够只展现渠道的图标。当用户看到渠道图标时,通过点击挑选以确认渠道,而且渠道挑选单张身份卡只能挑选一个渠道。

有了根底的主意后,咱们来完结这个交互逻辑。

首要需求创建一个渠道展现的数据集合,咱们声明一个数据用于寄存数据,如下代码所示:

private let platforms = [
        ("稀土技能社区", "icon_juejin"),
        ("CSDN博客", "icon_csdn"),
        ("阿里云社区", "icon_aliyun"),
        ("华为云社区", "icon_huaweiyun"),
    ]

上述代码中,咱们声明晰一个常量数组platforms,在platforms数组内有两个内容,前一个参数是渠道称谓,后一个参数是渠道图标。

声明好数据后,咱们来创建渠道挑选款式部分,这次需求用到的SwiftUI控件是LazyVGrid笔直网格布局容器,LazyVGrid笔直网格布局容器相似VStack笔直布局容器,不同的是VStack笔直布局容器只能将内部的元素笔直排布,而LazyVGrid笔直网格视图容器能够坚持笔直布局的情况下,将内部的元素分为几列,如下图所示:

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

LazyVGrid笔直网格布局容器运用需求提前声明网格的列数,如下代码所示:

 private var gridItemLayout = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]

上述代码中,咱们声明晰布局容器的GridItem列项为4列自适应调整的列项,将参数赋予变量值gridItemLayout。

紧接着咱们来运用LazyVGrid笔直网格布局容器,LazyVGrid笔直网格布局容器的运用办法和List列表的运用办法相似,通过与ForEach循环遍历配合运用,咱们依旧运用独自构建视图的办法创建它,如下代码所示:

// 渠道挑选器
func platformPicker() -> some View {
    LazyVGrid(columns: gridItemLayout, spacing: 10) {
        ForEach(0 ..< platforms.count, id: .self) { item in
            Image(platforms[item].1)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 48, height: 48)
                .clipShape(Circle())
        }
    }
}

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

上述代码中,咱们创建了“挑选渠道”视图platformPicker,在platformPicker视图中运用LazyVGrid笔直网格布局容器建立网格视图,LazyVGrid的columns列项为上面声明的gridItemLayout,网格之间元素的spacing间距为10。

和List列表的办法相同,咱们运用ForEach循环遍历platforms数组的数据,并运用了Image图片控件来展现platforms数组中的数据。因为platforms数组运用两个数据,因而咱们运用下标法指向数组的第二个数据(计算机数据从0开端计数)。

在这里还需求考虑一个问题,当咱们渠道图标太多时,可能会占有整个App的页面,咱们能够在LazyVGrid笔直网格布局容器最外层增加一个ScrollView翻滚视图容器,并设置翻滚视图的高度,如此LazyVGrid笔直网格布局容器不管有多少元素,都只会在ScrollView翻滚视图容器中展现,如下代码所示:

ScrollView {
            LazyVGrid(columns: gridItemLayout, spacing: 10) {
                ForEach(0 ..< platforms.count, id: .self) { item in
                    Image(platforms[item].1)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 48, height: 48)
                        .clipShape(Circle())
                }
            }
        }
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(8)
        .padding(.horizontal)
        .frame(maxHeight: 180)

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

很好,完结了“渠道挑选器”的款式之后,咱们来完结交互逻辑部分,首要咱们要看到用户点击挑选的渠道是哪一个,并将其凸显出来。

因为ForEach是遍历数据给到了item,因而当用户点击了指定的item时,该item对应的款式与其他未选中的款式分离隔。为了完结这个作用,咱们首要要声明一个变量,知道选中的是哪一个item,如下代码所示:

 @State var selectedItem = 0

当选中时,即item的值等于selectedItem时,咱们设置图片加一层边框,假如不是,则坚持原样,如下代码所示:

if item == selectedItem {
    Image(platforms[item].1)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 48, height: 48)
        .clipShape(Circle())
        .overlay(
            Circle()
                .stroke(Color.green, lineWidth: 4)
        )
} else {
    Image(platforms[item].1)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 48, height: 48)
        .clipShape(Circle())
		.onTapGesture {
        	selectedItem = item
	}
}

上述代码中,咱们通过判别当前的item是否等于selectedItem来构建不同的图片款式,假如共同,则Image图片运用overlay修饰符覆盖一层绿色的圆形边框。假如不共同,则坚持本来的款式,在原有的款式上增加onTapGesture点击事情,当点击的时分,让selectedItem选中的item等于点击的item。

能够在模拟器上试试作用,如下图所示:

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

别的,当点击渠道图标时,咱们需求给声明的变量进行赋值,如下代码所示:

platformIcon = platforms[item].1
platformName = platforms[item].0

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

如此,便完结了“自定义渠道挑选器”的一切内容。

界面规划:链接地址多行文本框

接下来咱们来完结链接地址的交互规划,TextEditor多行文本框控件和TextField输入框控件的运用办法相似,不同的是至今TextEditor多行文本框控件都没有提供placeholder提示文字的设置办法,只能由开发者自行完结。

不过不要紧,完结多行文本框的办法及其提示文字的办法也很简单,如下代码所示:

// 链接地址
func indexURLView() -> some View {
    ZStack(alignment: .topLeading) {
        TextEditor(text: $indexURL)
            .font(.system(size: 17))
            .padding(15)
        if indexURL.isEmpty {
            Text("请输入主页链接")
                .foregroundColor(Color(UIColor.placeholderText))
                .padding(20)
        }
    }
    .background(Color(.systemGray6))
    .cornerRadius(8)
    .padding()
    .frame(maxHeight: 240)
}

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

上述代码中,咱们创建了一个多行文本框视图indexURLView作为链接地址的输入框,在indexURLView视图中运用ZStack仓库视图建立层级联系,当TextEditor输入框的绑定的内容indexURL为空时,则展现一个Text文本作为提示文字。

如此就完结了TextEditor多行文本框及其提示文字的交互。

交互规划:增加身份卡按钮及其办法

完结增加身份卡的页面元素后,咱们来完结将输入的内容增加到“个人主页”的办法。

首要咱们先创建根本的按钮,如下代码所示:

// 增加按钮
func addBtn() -> some View {
    Button(action: {
    }) {
        Text("增加")
            .font(.system(size: 17))
            .foregroundColor(.white)
            .bold()
            .padding()
            .frame(maxWidth: .infinity)
            .background(Color.green)
            .cornerRadius(8)
            .padding(.horizontal)
    }
}

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

回到NewView的Body部分,一切元素咱们均以建立完结,一切视图的排布咱们能够运用VStack笔直布局容器进行排布,如下代码所示:

VStack(spacing: 15) {
    titleInputView()
    platformPicker()
    indexURLView()
    addBtn()
    Spacer()
}

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

款式完结之后,咱们来完结增加身份卡到个人主页的交互。

咱们来到Model.swift数据模型文件,本来咱们声明晰models数组变量,咱们需求将其剪切到ContentView文件中来,作为ContentView中的一部份,用于后面的数据双向绑定运用,如下图所示:

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

然后回到NewView文件中,声明用于双向绑定的数据模型,如下代码所示:

@Binding var models: [Model]

因为运用了@Binding进行双向绑定参数,因而NewView中不能存在private声明的变量,因而咱们需求删去本来platforms数组和gridItemLayout网格布局的private,而且给NewView赋予默认值,如下代码所示:

NewView(models: .constant([]))

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

还需求回到ContentView文件,对运用NewView视图中声明的双向绑定的models进行绑定,如下图所示:

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

最终咱们还需求回到NewView视图中,完结增加身份卡的办法,如下代码所示:

let newItem = Model(platformIcon: platformIcon, title: title, platformName: platformName, indexURL: indexURL)
models.append(newItem)

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

上述代码中,咱们在点击addBtn增加按钮时,完结增加身份卡的办法,首要先声明一个常量newItem寄存契合Model数据模型的数据,并将数据模型的对应的值填充为咱们在NewView声明的变量(因为采用相同的命名,因而就有了上面的作用),然后调用append的办法将契合数据模型的数据增加到models数组中。

此时咱们就能够删去NewView中声明的变量的默认值,让用户自定定义填充,如下代码所示:

@State var title: String = ""
@State var indexURL: String = ""

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

同时咱们也能够删去在ContentView中models数组的默认值,让咱们自己操作创建数据,如下代码所示:

@State var models:[Model] = []

实战教程元宇宙来了,准备好你的电子名片了吗?(三)

全体预览

接下来,让咱们在模拟器中操作电子名片App的全路径,如下图所示:

本章小结

在本章中,咱们学习了怎么建立“增加身份卡”页面,包含输入框根底控件的运用,多行文本框根底控件的运用。

本章的中心内容是自定义挑选器的创建,咱们运用ScrollView翻滚视图容器、LazyVGrid笔直网格容器建立了挑选器,并完结了单选的功用。最终咱们通过双向绑定视图数组数据的方式,完结了增加身份卡到个人主页的办法。

在本章的例子中,其实能够运用到其他App案例中,最常见的示例:todo待办事项和note笔记。

下面的章节中,咱们来继续学习点击身份卡片在App打开浏览器并拜访链接地址的功用及其他相关操作,请坚持期待吧~

版权声明

本文为稀土技能社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!