网站首页 > 开源技术 正文
Landmarks App的主界面显示了一个可滚动的分类列表,在每个分类中有可以水平滑动的地标数据。在我们构建这个基本的导航功能时,我们可以探索如何组合视图可以适配不同设备的尺寸和旋转方向。
<下载>启动项目并跟随本教程,或打开完成的项目自己研究代码。
01 添加主页视图
现在我们已经有了所有Landmarks App需要的视图,是时候添加一个主页--一个将所有视图统一的视图。主页视图不仅仅是包含所有其它视图,还提供了导航到显示地标的方式。
第一步
新建一个Home.swift文件,并在文件中创建一个自定义的视图
import SwiftUI
struct CategoryHome: View {
var body: some View {
Text("Landmarks Content")
}
}
struct CategoryHome_Previews: PreviewProvider {
static var previews: some View {
CategoryHome()
}
}
第二步
将SceneDelegate.swift文件中的默认显示的地标列表改为显示新创建的CategoryHome视图。
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(
rootView: CategoryHome()
.environmentObject(UserData())
)
主页视图是作为Landmarks App的基本,所以它需要一个方式来展现所有的其它视图。
第三步
在Home.swift文件中,为CategoryHome添加一个NavigationView视图来托管Landmarks中的不同视图。
使用导航视图配合NavigationLink实例及相关的修饰器构建App中的导航层级结构。
struct CategoryHome: View {
var body: some View {
NavigationView {
Text("Landmarks Content")
}
}
}
第四步
将导航栏的标题设置为Featured。
NavigationView {
Text("Landmarks Content")
.navigationBarTitle(Text("Featured"))
}
}
02 创建分类列表
Landmarks App为了便于浏览将所有的分类分成不同的行并竖直排列。我们通过组合竖直和水平stack,以及在列表中添加滚动功能实现。
第一步
使用Dicionary结构体的init(grouping:by:)初始化器及地标的分类属性将地标分成不同的组。
初始项目文件中包含了为每个地标预定义的分类。
struct CategoryHome: View {
var categories: [String: [Landmark]] {
Dictionary(
grouping: landmarkData,
by: { $0.category.rawValue }
)
}
var body: some View {
NavigationView {
第二步
在Landmarks中使用列表显示分类。
Landmark.Category字段名用来区分列表中的每个条目,这个字段是枚举类型,所以一定是唯一的。
var body: some View {
NavigationView {
List {
ForEach(categories.keys.sorted(), id: \.self) { key in
Text(key)
}
}
.navigationBarTitle(Text("Featured"))
}
}
03 添加每行的地标
Landmarks显示的每一行分类都可以水平滑动。添加一个新的视图类型来显示行,然后将所有的这个分类下的地标添加到这行中。
第一步
创建一个新的文件CategoryRow.swift并定义一个新的自定义视图CategoryRow用来存放分类行的内容。
这个视图需要存储指定分类中的地标信息用于显示。
struct CategoryRow: View {
var categoryName: String
var items: [Landmark]
var body: some View {
Text(self.categoryName)
.font(.headline)
}
}
struct CategoryRow_Previews: PreviewProvider {
static var previews: some View {
CategoryRow(categoryName: landmarkData[0].category.rawValue, items: Array(landmarkData.prefix(4)))
}
}
第二步
更新Home.swift文件中CategoryHome类型的body属性,将分类信息传入新创建的CategoryRow类型
List {
ForEach(categories.keys.sorted(), id: \.self) { key in
CategoryRow(categoryName: key, items: self.categories[key]!)
}
}
第三步
切换要CategoryRow.swift将分类中的地标显示在HStack中。
var body: some View {
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
Text(landmark.name)
}
}
}
}
第四步
通过使用frame(width:height:)指定高度并将stack嵌套进一个滚动视图让行视图的内容有更合理的空间。
使用更大样本的数据来更新视图预览可以更容易确定滚动表现正常。
var body: some View {
VStack(alignment: .leading) {
Text(self.categoryName)
.font(.headline)
.padding(.leading, 15)
.padding(.top, 5)
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
Text(landmark.name)
}
}
}
.frame(height: 185)
04 组合主页视图
Landmarks App的主页在用户点击查看详情前需要简单地显示地标。
这里我们复用部分在<创建和组合视图>教程中创建的Landmark视图创建一个熟悉但简单的地标预览图。
第一步
在CategoryRow.swift文件中,创建一个新的自定义视图CategoryItem,并将CategoryRow类型中的用来显示地标名称的Text视图替换为新创建的视图。
struct CategoryItem: View {
var landmark: Landmark
var body: some View {
VStack(alignment: .leading) {
landmark.image
.resizable()
.frame(width: 155, height: 155)
.cornerRadius(5)
Text(landmark.name)
}
.padding(.leading, 15)
}
}
struct CategoryRow: View {
var categoryName: String
var items: [Landmark]
// 省略部分代码
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
CategoryItem(landmark: landmark)
}
}
第二步
在Home.swift文件中,添加一个名为FeaturedLandmarks的简单视图只显示那些被标记为isFeatured重要的地标。
在后面的教程中,我们会将这个视图变成一个交互式的跑马灯。现在,它还只是显示重要地标其中一个的被缩放和剪切的预览图片。
struct FeaturedLandmarks: View {
var landmarks: [Landmark]
var body: some View {
landmarks[0].image.resizable()
}
}
struct CategoryHome: View {
// 省略部分代码
var featured: [Landmark] {
landmarkData.filter { $0.isFeatured }
}
var body: some View {
NavigationView {
List {
FeaturedLandmarks(landmarks: featured)
.scaledToFill()
.frame(height: 200)
.clipped()
ForEach(categories.keys.sorted(), id: \.self) {
第三步
将所有类型的地标预览图片的边距设置为0,让内容可以扩展到显示的边缘。
.frame(height: 200)
.clipped()
.listRowInsets(EdgeInsets())
ForEach(categories.keys.sorted(), id: \.self) { key in
CategoryRow(categoryName: key, items: self.categories[key]!)
.listRowInsets(EdgeInsets())
05 在各模块之间添加导航
现在所有不同分类的地标在主页视图都可见了,用户需要一种方式可以去到App的其它模块。使用导航和展现API让详情页、收藏列表以及用户档案都可以从主页导航过去。
第一步
在CategoryRow.swift文件中,用NavigationLink将CategoryItem包裹起来。
分类条目本身作为按钮的标签,它的目标是卡片显示的地标的详情视图。
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
NavigationLink(
destination: LandmarkDetail(
landmark: landmark
)
) {
CategoryItem(landmark: landmark)
}
}
}
第二步
使用renderingMode(_:)和foregroundColor(_:)修饰器改变分类条目的导航外观。
默认情况下,传入导航链接作为标签的文本会使用环境中的强调色,图片会渲染为模板图片,这些表现我们都可以修改以适配我们的设计。
VStack(alignment: .leading) {
landmark.image
.renderingMode(.original)
.resizable()
.frame(width: 155, height: 155)
.cornerRadius(5)
Text(landmark.name)
.foregroundColor(.primary)
.font(.caption)
第三步
在Home.swift文件中,添加一个弹出页,在用户点击了标签栏的档案图标后用一个模态视图显示用户档案。
SwiftUI在showProfile状态变量设置为true的时候显示用户档案,并在showProfile设置为false的时候隐藏。
}
@State var showingProfile = false
var body: some View {
NavigationView {
第四步
在导航栏添加一个按钮,当按钮被点击的时候将showProfile的值从false转为true。
@State var showProfile = false
var profileButton: some View {
Button(action: { self.showProfile.toggle()}) {
Image(systemName: "person.crop.circle")
.imageScale(.large)
.accessibility(label: Text("User Profile"))
.padding()
}
}
var body: some View {
// 省略部分代码
}
.navigationBarTitle(Text("Featured"))
.navigationBarItems(trailing: profileButton)
.sheet(isPresented: $showProfile) {
Text("User Profile")
}
}
第五步
最后添加一个导航链接到可筛选的全部地标列表页面完成主页面。
}
.listRowInsets(EdgeInsets())
NavigationLink(destination: LandmarkList()) {
Text("See All")
}
}
.navigationBarTitle(Text("Featured"))
第六步
在LandmarkList.swift文件中,移除包裹地标列表的NavigationView,并在预览中添加它。
在App上下文中,LandmarkList总是会在Home.swift中声明的导航视图中展示。
var body: some View {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
猜你喜欢
- 2024-11-21 开发语音控制,我得到了这些经验!
- 2024-11-21 全球著名电脑周边厂商罗技 , 推出了家庭安防摄像头
- 2024-11-21 「mCaffeine」获 570 万美元 B 轮融资,提供咖啡因个人护理产品
- 2024-11-21 Android指示器,轮播与循环轮播
- 2024-11-21 SF Symbols完全指南
- 2024-11-21 如何查看QQ上的共同好友数量与详情
- 2024-11-21 苹果用户如何打造自己的智能家居系统
- 2024-11-21 Serverless 实战:如何为你的头像增加点装饰?
- 2024-11-21 罗技发布新型Circle View智能相机 支持苹果HomeKit
- 2024-11-21 罗技推出支持HomeKit Secure Video的智能门铃:售价199美元
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)