SwiftUI实战三:创建List视图和导航Navigation
系统: Mac OS 10.15.1, XCode 11.2.1,swift 5.0
写作时间:2019-11-30
1. 说明
此例子包含元素:List视图(代替以前的TableView), 导航。这个例子接着上一个例子SwiftUI实战二:组合视图和地图视图,把它当作详情页。
细节请查看官网教程
2. 元素以及代码下载
https://github.com/zgpeace/BuildingListsAndNavigation
初始项目请用以下目录StartingPoint > Landmarks
3. 数据模型
Landmark.swift
定义了struct
结构体数据的字段,
landmarkData.json
存储了列表数据
Data.swift
实现加载文件landmarkData.json
里的数据,并构建为Landmark.swift
模型数组let landmarkData: [Landmark] = load("landmarkData.json")
LandmarkDetail.swift
的内容就是上一节ContentView.swift
里面的内容.
Landmark.swift
需要实现协议Identifiable
,否则在List调用会报错。
Lists work with identifiable data. You can make your data identifiable in one of two ways: by passing along with your data a key path to a property that uniquely identifies each element, or by making your data type conform to the Identifiable protocol.
import SwiftUI
import CoreLocationstruct Landmark: Hashable, Codable, Identifiable {var id: Intvar name: Stringfileprivate var imageName: Stringfileprivate var coordinates: Coordinatesvar state: Stringvar park: Stringvar category: Categoryvar locationCoordinate: CLLocationCoordinate2D {CLLocationCoordinate2D(latitude: coordinates.latitude,longitude: coordinates.longitude)}enum Category: String, CaseIterable, Codable, Hashable {case featured = "Featured"case lakes = "Lakes"case rivers = "Rivers"}
}extension Landmark {var image: Image {ImageStore.shared.image(name: imageName)}
}struct Coordinates: Hashable, Codable {var latitude: Doublevar longitude: Double
}
4. 创建Cell行视图
实现结果图如下:
创建SwiftUI view
, 命名为 LandmarkRow.swift
.
//
// LandmarkRow.swift
// Landmarks
//
// Created by zgpeace on 2019/11/30.
// Copyright © 2019 Apple. All rights reserved.
//import SwiftUIstruct LandmarkRow: View {var landmark: Landmarkvar body: some View {HStack() {landmark.image.resizable().frame(width: 50, height: 50)Text(landmark.name)}}
}struct LandmarkRow_Previews: PreviewProvider {static var previews: some View {Group {LandmarkRow(landmark: landmarkData[0])LandmarkRow(landmark: landmarkData[1])}.previewLayout(.fixed(width: 300, height: 70))}
}
代码解析:
- 预览分组: Group可以同时预览多个视图
- previewLayout: 可以设置大小
预览效果:
5. 创建List视图
新建SwiftUI view
, 命名为 LandmarkList.swift
.
import SwiftUIstruct LandmarkList: View {var body: some View {NavigationView {List(landmarkData) { landmark inNavigationLink(destination: LandmarkDetail(landmark: landmark)) {LandmarkRow(landmark: landmark)}}.navigationBarTitle(Text("Landmarks"))}}
}struct LandmarkList_Previews: PreviewProvider {static var previews: some View {ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName inLandmarkList().previewDevice(PreviewDevice(rawValue: deviceName))}}
}
代码解析:
NavigationView
: 添加导航栏.navigationBarTitle(Text("Landmarks"))
:导航栏设置titleNavigationLink(destination: LandmarkDetail(landmark: landmark))
:点击子项跳转到详情页
预览效果如下:
6. 圆形图片页数据改为动态获取
import SwiftUIstruct CircleImage: View {var image: Imagevar body: some View {image.clipShape(Circle()).overlay(Circle().stroke(Color.white, lineWidth: 4)).shadow(radius: 10)}
}struct CircleImage_Previews: PreviewProvider {static var previews: some View {CircleImage(image: landmarkData[0].image)}
}
预览效果:
7. 地图页面数据改为动态获取
import SwiftUI
import MapKitstruct MapView: UIViewRepresentable {var coordinate: CLLocationCoordinate2Dfunc makeUIView(context: Context) -> MKMapView {MKMapView(frame: .zero)}func updateUIView(_ view: MKMapView, context: Context) {let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)let region = MKCoordinateRegion(center: coordinate, span: span)view.setRegion(region, animated: true)}
}struct MapView_Previews: PreviewProvider {static var previews: some View {MapView(coordinate: landmarkData[0].locationCoordinate)}
}
需要Live Preview才能看到地图:
8. 详情页数据改为动态获取
import SwiftUIstruct LandmarkDetail: View {var landmark: Landmarkvar body: some View {VStack {MapView(coordinate: landmark.locationCoordinate).edgesIgnoringSafeArea(.top).frame(height: 300)CircleImage(image: landmark.image).offset(x: 0, y: -130).padding(.bottom, -130)VStack(alignment: .leading) {Text(landmark.name).font(.title)HStack(alignment: .top) {Text(landmark.park).font(.subheadline)Spacer()Text(landmark.state).font(.subheadline)}}.padding()Spacer()}.navigationBarTitle(Text(landmark.name), displayMode: .inline)}
}struct LandmarkDetail_Previews: PreviewProvider {static var previews: some View {LandmarkDetail(landmark: landmarkData[0])}
}
预览效果:
9. SceneDelegate初始页面更新
变动的函数如下:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).// Use a UIHostingController as window root view controllerif let windowScene = scene as? UIWindowScene {let window = UIWindow(windowScene: windowScene)window.rootViewController = UIHostingController(rootView: LandmarkList())self.window = windowwindow.makeKeyAndVisible()}
}
10. 还可以设置device为iPad预览
参考
https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation
https://developer.apple.com/tutorials/swiftui/tutorials
SwiftUI实战三:创建List视图和导航Navigation相关推荐
- SwiftUI实战创建Tinder样式的可左右滑动卡视图
本文价值与收获 看完本文后,您将能够作出下面的界面 Jietu20200412-110347@2x.jpg Jietu20200412-110524.gif 在本文中,我想向您展示如何仅用几行代码就能 ...
- SwiftUI实战教程之创建Tinder样式的可左右滑动卡视图(项目含源码)
本文价值与收获 看完本文后,您将能够作出下面的界面 在本文中,我想向您展示如何仅用几行代码就能实现类似Tinder的卡片视图和行为(轻拂以行动). 为此,我们需要执行以下操作: 创建用户视图 创建Na ...
- IOS开发-表视图LV3导航控制器
学到这里感觉有点难了,其实这篇文章再草稿箱里放了好久了~ 最近对于学习的热情下降了.这不行-抓紧学习走起! 在这一章节的学习中主要针对导航控制器及表视图来建立多视图的应用, 首先要了解一些概念-- 1 ...
- Unity的使用(四):预制体,创建地形和地形导航
前面介绍了Unity游戏引擎的基础功能,现在终于要进入到游戏开发中了.那么,一款游戏开发要有资源,这个一般是由美术提供的,我们只需要负责程序方面的事.那么,怎么将获得的资源应用起来呢? 一. 导入资源 ...
- Office 365 系列三 ------ 创建Office 365普通账号
当我们购买或者试用Office 365的时候,微软或者世纪互联会发一封邮件给我们,里面就只有管理员的账号,那么作为我们IT 管理员应该给员工创建账号, 创建的过程如下: 一.登陆: http://po ...
- Tableau实战系列构建基本视图以浏览数据
前言 本主题使用 Sample - Superstore 数据源演练如何创建基本视图和浏览数据.它演示 Tableau中的数据视图在你的探究过程中如何发生演变. 关于tableau的高级部分内容,大家 ...
- 【Qt】数据库实战(三)
00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 增删改查操作 04. 名字绑定和位置绑定 05. 程序示例 06. 批处理操作 07. 事务操作 08. 附录 01. 概 ...
- [python opencv 计算机视觉零基础到实战] 三、numpy与图像编辑
一.学习目标 了解图片的通道与数组结构 了解使用numpy创建一个图片 了解使用numpy对图片的一般操作方法 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的hell ...
- 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面
原文:学习ASP.NET Core Razor 编程系列三--创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 ...
- 实战三:手把手教你实现物体识别
实战三:手把手教你实现物体识别 一.基于Haad+Adaboost实现人脸识别 1.原理介绍(参考下面的博客文章) http://www.cn ...
最新文章
- Xcode升级到8之后的一些需要我们手动配置的地方
- Linux下为什么ls直接就可以运行,而你的程序要写./dir1/dir2/bin/bwa才可以
- 雷林鹏分享:XML 命名空间
- android MotionEvent
- NUC970开发资源
- 解决“打开ArcGIS Server Manager”网页无反应为空白的情况
- 使用ajax预加载图片
- 使用eclipse开发javaweb登录功能带验证码文件下载第几位登录使用servlet编写html
- Angular 4.x 事件管理器及自定义EventManagerPlugin
- php可以调用windowsapi吗_2.如何调用WindowsApi
- 基于 bootstrap 字体图标,用纯CSS实现星级评分功能
- [codeforces538E]Demiurges Play Again
- element tree不刷新视图_安卓从入门到进阶第五章(视图查看)
- 正定矩阵、正定矩阵与极值的关系、黑塞矩阵、牛顿法
- ARINC 429 过滤介绍
- Java NIO?看这一篇就够了!
- 关于我学前端一年的体验(心得)
- 即时通讯IM,是时代进步的逆流?看看JNPF怎么说
- 使用父子两个进程拷贝同一个文件,父进程拷贝前一半,子进程拷贝后一半。
- Linux环境下搭建Apache服务器(完整版)
热门文章
- web项目设计文档_web项目前后端分离模式下的权限设计方案
- php兼容net的md5,解决c# md5与php md5加密不一致的问题(md5(unicode))
- hibernate java.util.date 精度_hibernate中java.util.Date类型映射
- Vue中如何导入并读取Excel数据
- Js时间相关处理函数
- 配置防盗链 访问控制Directory 访问控制FilesMatch
- crontab使用环境变量
- CentOS配置Nginx官方的Yum源 及yum安装php
- Made in 大产品——技术商业盛典
- 深圳465亿建11代生产线,TCL三星带头认购股权