无人问津的设置页面,如何做到小而精美?
项目背景
使用掘金App以来,对于掘金App端的设计风格和交互都是比较满意的。但某一天当我无聊点开“设置”页面的时候,一股浓浓的“不协调感”扑面而来。
啊这……这也太原始了吧,一点都不优雅。我不能让这种不优雅一直存在,于是就动手尝试做一个新的“设置”页面。
项目搭建
首先,创建一个新的SwiftUI
项目,命名为SettingView
。
页面样式
我们先来看下修改后最终的效果,示例:
在绘制整个页面之前,我们需要先行分析整个页面的结构,它包括顶部导航、个人信息栏、设置功能栏、退出登录按钮组成。
因此,在我们最开始写代码时,需要梳理好页面结构部分。
顶部导航
对于顶部导航栏来说,我们可以使用NavigationView
构建标准的顶部导航。示例:
NavigationView { ZStack { Color(red: 246 / 255, green: 246 / 255, blue: 246 / 255).edgesIgnoringSafeArea(.all) } .navigationBarTitle("设置", displayMode: .inline) }
上述代码中,我们除了使用navigationBarTitle
修饰符创建标题外,还使用ZStack
叠加视图和edgesIgnoringSafeArea
修饰符,给整个页面填充了一个背景颜色。
对于左侧返回按钮,我们可以单独构建样式,示例:
// 返回上一页 private var backToMineView: some View { Button(action: { }) { Image(systemName: "arrow.backward") .foregroundColor(.black) } }
再使用navigationBarItems
修饰符创建导航栏按钮,示例:
.navigationBarItems(leading: backToMineView)
个人信息栏
个人信息栏目需要突出个人的基础的账号信息,这里考虑的是使用用户头像、用户昵称、用户职务作为主要展示信息。示例:
// 个人信息 private var mineMessageView: some View { Button(action: { }) { HStack(spacing: 15) { Image("me") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 60) .clipShape(Circle()) .overlay(Circle().stroke(Color(.systemGray5), lineWidth: 1)) VStack(alignment: .leading, spacing: 5) { Text("文如秋雨") .font(.system(size: 17)) .foregroundColor(.black) Text("高级产品经理") .font(.system(size: 14)) .foregroundColor(.gray) } } .padding(.vertical, 10) } }
上述代码中,我们使用Image
和Text
构建样式部分,文字部分使用VStack
纵向排布,整个文字部分和Image
图片采用HStack
横向排布,至于样式修饰符这里就不展开说了。
而在我们将视图展示前,我们还做需要做一件事情,由于个人信息栏、设置功能栏、退出按钮都是呈现分段式卡片效果,我们可以使用Form
表单和Section
段落来构建样式,示例:
Form { Section { mineMessageView } }
我们发现了存在2个问题,一是整个App
的背景颜色由于Form
表单的样式影响被覆盖了,二是整个个人信息栏缺少了右边的“向右”按钮。
关于表单样式部分被覆盖的情况,我们可以在渲染页面时去掉背景颜色,这个我们之前做过,示例:
init() { UITableView.appearance().backgroundColor = .clear }
而缺少“向右”的指示按钮,是因为我们要使用到基于NavigationView
顶部导航的跳转,当我们使用NavigationLink
作为跳转方法时,系统会自带指示按钮,所以在这里我们没有自己绘制按钮样式。
我们继续完成下面的内容。
设置功能栏
下一部分是设置功能栏,我们发现这样式之间有共通的地方,左侧图标加设置功能文字,右侧次要说明文字加跳转指示。
跳转指示我们依旧放在一边,我们面对具有相同样式式,常用的方式是抽离出来,这样可以减少代码量。示例:
// MARK: 栏目结构 struct listItemView: View { var itemImage: String var itemName: String var itemContent: String var body: some View { Button(action: { }) { HStack { Image(systemName: itemImage) .font(.system(size: 17)) .foregroundColor(.black) Text(itemName) .foregroundColor(.black) .font(.system(size: 17)) Spacer() Text(itemContent) .font(.system(size: 14)) .foregroundColor(.gray) }.padding(.vertical, 15) } } }
我们构建一个新的视图listItemView
,声明一个必要变量:itemImage
图标、itemName
功能名称、itemContent
功能次要文字。
然后构建基础的样式框架,使用HStack
构建横向视图,放置1个Image
图片、2个Text
文本。
构建好后,我们在新的的Section
段落中构建样式。示例:
Section { listItemView(itemImage: "lock", itemName: "账号绑定", itemContent: "已绑定") listItemView(itemImage: "gear.circle", itemName: "通用设置", itemContent: "") listItemView(itemImage: "briefcase", itemName: "简历管理", itemContent: "未上传") listItemView(itemImage: "icloud.and.arrow.down", itemName: "版本更新", itemContent: "Version 6.2.8") listItemView(itemImage: "leaf", itemName: "清理缓存", itemContent: "0.00MB") listItemView(itemImage: "person", itemName: "关于掘金", itemContent: "") }
退出登录按钮
最后是退出登录按钮,我们构建一个新的视图,示例:
// 退出登录 private var signOutView: some View { Button(action: { }) { Text("退出登录") .font(.system(size: 17)) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 30, maxHeight: 30) .foregroundColor(.red) .cornerRadius(8) .padding(.vertical, 5) } } 我们也在新的段落中构建样式,示例: less 复制代码 var body: some View { NavigationView { ZStack { Color(red: 246 / 255, green: 246 / 255, blue: 246 / 255).edgesIgnoringSafeArea(.all) Form { Section { mineMessageView } Section { listItemView(itemImage: "lock", itemName: "账号绑定", itemContent: "已绑定") listItemView(itemImage: "gear.circle", itemName: "通用设置", itemContent: "") listItemView(itemImage: "briefcase", itemName: "简历管理", itemContent: "未上传") listItemView(itemImage: "icloud.and.arrow.down", itemName: "版本更新", itemContent: "Version 6.2.8") listItemView(itemImage: "leaf", itemName: "清理缓存", itemContent: "0.00MB") listItemView(itemImage: "person", itemName: "关于掘金", itemContent: "") } Section { signOutView } } } .navigationBarTitle("设置", displayMode: .inline) .navigationBarItems(leading: backToMineView) } }
项目展示
恭喜你,完成了本章的全部内容!
接下里的章节,我们将继续完成掘金App设置页面的功能详情页,敬请期待!
快来动手试试吧。