网站首页 > 开源技术 正文
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美元
 
欢迎 你 发表评论:
- 1590℃北京那些看上去很牛的车牌们!(北京厉害车牌)
 - 1107℃2025年度视频去水印软件TOP5对比:哪款最值得用
 - 683℃《我的世界》不同版本的差异 ——新手向
 - 595℃新疆话里的“虫子”
 - 516℃中兴光猫 Telnet下设置大全(中兴光猫命令大全)
 - 513℃蓝牙设备配对失败的系统性解决方案与技术解析
 - 509℃未备份电脑文件数据恢复的七种方法
 - 488℃工艺管道常用英文缩写 英汉对照
 
- 最近发表
 
- 标签列表
 - 
- 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)
 
 

本文暂时没有评论,来添加一个吧(●'◡'●)