文章目录

  • 1. 使用 GeometryReader 调整尺寸
  • 2. 滚动视图 ScrollView
  • 3. NavigationLink
  • 4. 使用 Codable 对多层级的 JSON 进行压缩
  • 5. 扩展Bundle
  • 6.案例
    • 6.1 json数据
    • 6.2 结构体定义
    • 6.3 BookView
    • 6.4 NovelView

1. 使用 GeometryReader 调整尺寸

.resizable() 设置图片尺寸是可以被调整的
.frame(width:300, height: 300) 调整图片尺寸
.aspectRatio(contentMode: .fit) 保持长宽比例
GeometryReader 可以使图片更好的显示

GeometryReader{ geo in
Image("road")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geo.size.width, height: 300)
}

2. 滚动视图 ScrollView

import SwiftUIstruct CustomText: View{var number: Intvar body: some View{Text("CustomText \(number)")}init(_ number: Int){self.number = numberprint("CustomText \(number)")}
}struct ContentView: View {var body: some View {ScrollView(.vertical){VStack{ForEach(0...100, id:\.self){CustomText($0).font(.title)}}}}
}

3. NavigationLink

SwiftUI中的NavigationView采用的是“视图堆栈”的操作机制。它会在APP界面的顶部显示一个导航栏,用来指示我们当前是哪一个视图。

所谓的“视图堆栈”机制就是当前显示的视图是在“栈顶”的,当需要打开新的视图时,就把新的视图‘‘入栈”,让这个新的视图称为新的栈顶。当我们在导航栏中点击“back”时,相当于让当前的视图“出栈”,而之前在栈中“原来栈顶”下面的那个视图就成了“新的栈顶

import SwiftUI
struct ContentView: View {var body: some View {NavigationView{NavigationLink(destination: Text("world")){Text("Hello")}.navigationBarTitle("SwiftUI")}}
}

上述代码中的第6行使用了NavigationLink来创建导航,它的参数destination可以是任何view类成员,一个Text,一个button,-个view均可。
这种机制跟之前学过的“sheet”的方式显示新的视图是不一样的。

  • NavigationLink 有些类似于剥洋葱,-层一层的剥开,一层一层的深入去展示。

  • sheet有些类似于它就是这个视图的一个组成部分,只不过不需要显示它的时候就把它隐藏起来,需要的时候再让它显示出来。

    如果在NavigationLink中使用了List, 那么会在每- -行的后面都出现一一个“>”,用于指示用户点击可进入下一层。

4. 使用 Codable 对多层级的 JSON 进行压缩

// ****** ?? 3?******
Button("解析圆形"){let myCircle = """
{"radius": 10.4,
"point": {"x": 12.0,
"y": -15.3
}
"""
}struct Circle: Codable{var radius: Doublevar point: PointXY
}
struct PointXY: Codable{var x: Doublevar y: Double
}//解析上面数据的代码let data = Data(myCircle.utf8)let decoder = JSONDecoder()if let circle = try? decoder.decode(Circle.self, from: data) {print(circle.point.x)}
}

5. 扩展Bundle

// ****** Astronaut.swift ******
import Foundation
struct Astronaut: Codable, Identifiable{var id: Intvar name: Stringvar description: String
}
// ****** Bundle-Decodable.swift ******
import Foundation
extension Bundle {func decode<T: Codable>(_ file: String) -> T {guard let url = self.url(forResource: file, withExtension: nil) else {fatalError("Failed to locate \(file) in bundle.")}guard let data = try? Data(contentsOf: url) else {fatalError("Failed to load \(file) from bundle.")}let decoder = JSONDecoder()guard let loaded = try? decoder.decode(T.self, from: data)  else {fatalError("Failed to decode \(file) from bundle.")}return loaded}
}

在ContentView中编写代码

let astronauts = Bundle.main.decode("astronaut.json")

6.案例

6.1 json数据

novels.json

[{"id": 1,"list": [{"name": "两钱铜币","author": "(日)江户川乱步"},{"name": "人生","author": "路遥"},{"name": "鬼谷子的局","author": "寒川子"}],"description": "电子书畅销小说"},{"id": 2,"sort": "社会生活小说","list": [{"name": "人生","author": "路遥"},{"name": "边城","author": "沈从文"},{"name": "海边的卡夫卡","author": "(日)村上春树"}],"description": "《人生》是获得茅盾文学奖的作品,《边城》是我国文学大师沈从文久负盛名的作品,《海边的卡夫卡》是村上春树仅次于《挪威的森林》的重要长篇小说。"},{"id": 3,"sort": "历史小说","list": [{"name": "鬼谷子的局","author": "寒川子"},{"name": "巨人的陨落","author": "(英)肯·福莱特"}],"description": "《鬼谷子的局》是一部巨著,全书共十卷,讲述谋略家、兵法家、纵横家、阴阳家、道家共同的祖师爷——鬼谷子布局天下的辉煌传奇。《巨人的陨落》是全球读者平均3个通宵读完的超级巨著。碾压全球畅销榜的伟大故事,全球每三秒卖出一本!"},{"id": 4,"sort": "侦探悬疑小说","list": [{"name": "两钱铜币","author": "(日)江户川乱步"},{"name": "梦幻花","author": "(日)东野圭吾"},{"name": "无人生还","author": "(英)阿加莎·克里斯蒂"}],"description": "当当网侦探悬疑推理类的热销小说"}
]

books.json

[{"id": "两钱铜币","author": "(日)江户川乱步 著 王志芳 译","price": "6.99","description": "江户川乱步(1894—1965)是日本久富盛名的推理作家、评论家,被誉为日本“侦探推理小说之父”,其笔下的侦探明智小五郎(《名侦探柯南》中毛利小五郎姓名由来,其本人为《名侦探柯南》中江户川柯南姓由来)更是日本家喻户晓的人物。 江户川乱步的中短篇代表作,小说内容取材广泛,构思拍案叫绝、气氛妖异诡谲、情节跌宕起伏,不读到最后一刻,永远不会知道真相是什么!本套书共分两册,将收录江户川乱步最为经典的侦探小说,例如《两钱铜币》《湖畔亭离奇命案》《月亮与手套》《心理测试》《地狱的面具》《出没于顶棚里的人》《D坂街杀人事件》等。"},{"id": "梦幻花","author": "(日)东野圭吾","price": "9.90","description": "错综交织的悬案,揭百年的谜团 年轻夫妇的身体被武士刀贯穿,仅有年幼的女儿生还; 一见钟情的初恋女孩,却在几天后人间蒸发; 大学生跳楼身亡,桌上摆着半杯可乐; 独居老人疑被室强盗杀害,丢失的财物却是一盆鲜花…… “梦幻花”究竟是什么?为什么一旦追寻就会自取灭亡? 源自真实故事的创作灵感 日本的江户时代出现过黄色的牵牛花。为什么到现在反而没有了呢? 想到这里,一股悬疑的气息袅袅升起。"},{"id": "无人生还","author": "(英)阿加莎·克里斯蒂","price": "6.99","description": "十个相互陌生、身份各异的人受邀前往德文郡海岸边一座孤岛上的豪宅。客人到齐后,主人却没有出现。当晚,一个神秘的声音发出指控,分别说出每个人心中罪恶的秘密。接着,一位客人离奇死亡。暴风雨让小岛与世隔绝,《十个小士兵》——这首古老的童谣成了死亡咒语。如同歌谣中所预言的,客人一个接一个死去……杀人游戏结束后,竟无一人生还!"},{"id": "人生","author": "路遥","price": "18.99","description": "《人生》是茅盾文学奖得主路遥的代表作,激励万千读者的文学经典。《人生》改变了马云的一生,也深刻影响了陈忠实、贾樟柯等人的创作。 《人生》以陕北高原的城乡生活为背景,叙述了知识青年高加林回到家乡又离家乡,再回归家乡的人生变化过程。《人生》讲述了一个年轻人面临的爱情与事业、理想与现实间的艰难选择,具有巨大的共情力量,说出了每个人,尤其是年轻人的困境、期待与追求。《人生》在有限生命中不懈追寻的激情,在每个人的心底激起回响;《人生》大地般宽广的气质,给予对生活失望的人莫大的安慰与力量。这是路遥的《人生》,也是我们每个人的人生。"},{"id": "边城","author": "沈从文","price": "5.99","description": "《边城》是沈从文久负盛名的作品,由此奠定了他在中国现代文学史上的地位。它入选“20世纪中文小说百强”第二名,并被翻译成40多个国家的文字出版,亦被编入美国、日本等十多个国家和地区的大学课本。 这是一部田园牧歌式的杰作。在这部小说中,沈从文描绘了一个如同世外桃源般的边城小镇,以及一个纯粹、美丽而淡淡忧伤的爱情故事。在他的笔下,湘西淳朴天然的人情世道,野性自由的生命形态,以及澄澈纯净的人性,均一一铺呈开来,婉约而惆怅。沈从文关于“爱”与“美”的美学理想,在这部小说中得到了完整的体现。 本书另外还收录了《三三》《萧萧》等沈从文具有代表性的小说作品,基本囊括了沈从文文字精髓,全面展示了大师的文风神采。"},{"id": "海边的卡夫卡","author": "(日)村上春树","price": "12.99","description": "本书是村上春树仅次于《挪威的森林》的重要长篇小说,以其独特风格的两条平行线展。一条平行线是少年“田村卡夫卡”,为了挣脱“你要亲手杀死父亲,与母亲乱伦”的诅咒,离家乡投成人世界。此后父亲在家被杀,他却疑心自己是在睡梦中杀父。他在一座旧图书馆遇到一位50岁的优雅女性,梦中却与这位女性的少女形象交合,而这位女性又可能是他的生母。一条平行线是一名失忆老人中田,因为一桩离奇的杀人事件走上逃亡之路,在汽车司机星野的帮助下恢复了遥远的战争记忆。书中对日本军国主义的复活表达了忧虑,对日本的文化传统作出了反思。本书平装本2003年由我社初版,此后于2007年更换了封面,并作了修订。2014年,我社又出版了本书的精装本,再次作了修订。因上一个平装本封面已经10年未变,故第三次更换本书封面设计,使这部名作焕发新的活力。"},{"id": "鬼谷子的局","author": "寒川子","price": "19.99","description": " 本书为《鬼谷子的局》第五卷。在本卷中天下大势瞬息万变,转眼间,四子山已过三年。庞涓习得《吴起兵法》,自觉技艺已成,告别鬼谷子和其余三人下山。他先齐,再魏,助魏惠王与七万齐军决战黄池,退秦、赵、韩联军,尽解魏围。 由此,庞涓封侯拜将,名扬天下。他的杀父仇人陈轸深惧报复,仓皇投秦。 另一方面,魏惠王急使太子申重金礼聘孙宾下山。下山前,鬼谷子为孙宾更名为“孙膑”。 之后孙膑辅佐庞涓献屯田之谋,使魏国军力财力迅速复苏,隐隐有称霸七国之相。这让苏秦、张仪也禁不住跃跃欲试,但鬼谷子却以学艺未成为由,刻意挽留二人,授予其纵横捭阖之术。"},{"id": "巨人的陨落","author": "(英)肯·福莱特(KenFollett)(著),于大卫(译)","price": "19.99","description": " 在第一次世界大战的硝烟中,每一个迈向死亡的生命都在热烈地生长――威尔士的矿工少年、刚失恋的美国法律系大学生、穷困潦倒的俄国兄弟、富有英俊的英格兰伯爵,以及痴情的德国特工……从充满灰尘和危险的煤矿到闪闪发光的皇室宫殿,从代表着权力的走廊到爱恨纠缠的卧室,五个家族迥然不同又纠葛不断的命运逐渐揭晓,波澜壮阔地展现了一个我们自认为了解,但从未如此真切感受过的20世纪。"}
]

6.2 结构体定义

Book

// ****** Book.swift ******
import Foundation
struct Book: Codable, Identifiable {let id: Stringlet author: Stringlet price: Stringlet description: String
}

Novel

// ****** Novel.swift *******
import Foundation
struct Novel: Codable, Identifiable{struct CrewList: Codable{let name: Stringlet author: String}let id: Intvar sortVar: String?let crew: [CrewList]let description: Stringvar displayName: String{"Novel \(id)"}var image: String{"novel \(id)"}//软解包if let sort = sortVar{}else{print("nil")}}

6.3 BookView

BookView

import SwiftUI
struct BookView: View {let book: Bookvar body: some View {GeometryReader{ geometry inScrollView(.vertical){VStack{Image(self.book.id).resizable().scaledToFit().frame(width: geometry.size.width)Text(self.book.author)Text(self.book.price)Text(self.book.description).padding().layoutPriority(1)}}}.navigationBarTitle(Text(book.id),displayMode: .inline)}
}struct BookView_Previews: PreviewProvider {static let books: [Astronaut] = Bundle.main.decode("books.json")static var previews: some View {BookView(book: books[0])}
}

6.4 NovelView

import SwiftUI
struct NovelView: View {struct CrewMember{let name: Stringlet author: Stringlet book: Book}let novel: Novellet books: [CrewMember]init(novel: Novel, books: [Book]){self.novel= novel//定义一个空的数组存放 booksvar matches = [CrewMember]()for member in novel.crew{if let match = books.first(where: {$0.id == member.name}){matches.append(CrewMember(name: member.name,author: member.author, book: match))}else{fatalError("Missing \(member)")}}//forself.books= matches}  var body: some View {GeometryReader{ geometry inScrollView(.vertical){VStack{Image(self.novel.image).resizable().scaledToFit().frame(maxWidth:geometry.size.width * 0.7).padding(.top)Text(self.novel.sort)Text(self.novel.description).padding()ForEach(self.books, id:\.id){ crewMember inNavigationLink(destination: BookView(book: crewMember.book)){HStack{Image(crewMember.book.id).resizable().frame(width: 83, height: 60).clipShape(Capsule())VStack(alignment:.leading){Text(crewMember.book.id).font(.headline)Text(crewMember.book.author).foregroundColor(.secondary)}Spacer()}.padding()}.buttonStyle(PlainButtonStyle())}Spacer(minLength: 25)}}}//GeometryReader.navigationBarTitle(Text(novel.displayName),displayMode: .inline)
}//View
}//NovelViewstruct NovelView_Previews: PreviewProvider {static let novels: [Novel] = Bundle.main.decode("novels.json")static let books: [Book] = Bundle.main.decode("books.json")static var previews: some View {NovelView(novel: novels[0], books: books)}
}

ContentView

【Swift】第9周 小说列表展示案例相关推荐

  1. 案例:用户信息列表展示||1. 需求 2. 设计 3. 开发4. 测试 5. 部署运维

    案例:用户信息列表展示 1. 需求:用户信息的增删改查操作 2. 设计: 1. 技术选型:Servlet+JSP+MySQL+JDBCTemplate+Druid+BeanUtils+tomcat   ...

  2. 案例:用户信息列表展示

    一.需求设计分析 1.需求:用户信息的增删改查操作      2.设计:            1.技术选型:Servlet+JSP+MySQL+JDBCTemplate+Duird+BeanUtil ...

  3. 案例:图书管理(包括图书列表展示,添加、修改、删除图书功能)

    案例:图书管理 功能如下: (1)图书列表 实现静态列表效果 基于数据实现模板效果 处理每行的操作按钮 (2)添加图书 实现表单的静态效果 添加图书表单域数据绑定 添加按钮事件绑定 实现添加业务逻辑 ...

  4. CSS盒子模型(border、padding、margin、圆角边框、盒子阴影、文字阴影、新闻列表综合案例、新浪导航栏案例)

    1. 网页布局的本质 首先利用CSS设置好盒子的大小,然后摆放盒子的位置. 最后把网页元素比如文字图片等等,放入盒子里面. 以上两步 就是网页布局的本质 2. 盒子模型(Box Model) 盒子模型 ...

  5. iOS开发-QQ好友列表展示

    那么今天给同学写了一个QQ好友列表展示的Demo,涉及很多的内部细节以及高度封装自定义的cell和自定义view,那么内部所用知识和细节全部呈现在代码和注释中,那么废话不多说直接上代码,先看效果图! ...

  6. web实验新浪邮箱、下拉小说列表、验证用户登录

    html.css.js 新浪邮箱 下拉小说列表 验证用户登录 新浪邮箱 1.制作以下的新浪 邮箱登录界面: 要求: 1)首先给文本框制作细边框样式,当鼠标放在文本框上时,输入框的边框颜色发生变化,当鼠 ...

  7. “小说列表模块”JAVA代码官方评审「在线实习·推推」

    在线实习是大拿老师为了正在准备校招的IT同学带来的免费项目,每期一个主题,业务模式简单且项目突出,适合作为校招的项目经历. 本期小拿带来的是在线实习「推推」项目"小说列表模块"的J ...

  8. “小说列表模块”前端代码官方评审「在线实习·推推」

    在线实习是大拿老师为了正在准备校招的IT同学带来的免费项目,每期一个主题,业务模式简单且项目突出,适合作为校招的项目经历. 本期小拿带来的是在线实习「推推」项目"小说列表模块"的前 ...

  9. Android Studio基于数组适配器使用列表视图案例 —— 阅读古诗

    一.列表视图概述 (一)继承关系图 列表视图(ListView)继承了抽象列表视图(AbsListView),而抽象列表视图又继承了适配器视图(AdapterView).适配器视图具有共同的特征,就是 ...

最新文章

  1. 配置Open***使用User/Pass方式验证登录
  2. Hive动态分区导致的Jobtracker Hang
  3. 如何更好的利用Node.js的性能极限
  4. Linux/Unix系统编程手册 第三章:系统编程概念
  5. java 文本工具类_干货:排名前16的Java工具类
  6. C. Code a Trie(Trie+dfs+贪心)
  7. Scripting elements ( lt;%!, lt;jsp:declaration, lt;%=, lt;jsp:expression, 错误的解决方法
  8. 背包问题九讲_背包问题
  9. 洛谷P1014 [NOIP1999 普及组] Cantor 表
  10. 软件设计师 - 算法思想
  11. c语言小游戏代码矿井逃生_如何选择编程语言和逃生教程炼狱
  12. FMPlayer组件说明
  13. mysql5.7 gtid问题_MySQL 5.7.5: 新语法WAIT_FOR_EXECUTED_GTID_SET 及存在的问题-阿里云开发者社区...
  14. python-指数分布介绍(scipy.stats.expon)
  15. 【金三银四】Java基础知识面试题(2021最新版)
  16. PHP implode和explode用法
  17. 修复计算机有什么用,电脑硬盘坏道修复了对以后电脑使用有什么影响吗?
  18. awk使用手册(全)
  19. 二叉排序树和平衡二叉树
  20. 适配器模式(对象适配器)

热门文章

  1. linux文件系统打开不了,linux文件系统之文件的打开与关闭
  2. 现代电气控制系统安装与调试装置
  3. JAVA 实习面试题大全必看
  4. java 获取登录ip_java如何获取客户端登入时的ip
  5. Linux后台开发系列之「11.IO 概述」
  6. vxi11协议服务器的实现,基于DSP和VXI-11协议的LXI仪器控制与实现.pdf
  7. js禁止原生手机返回键(物理返回键)
  8. 为什么微波炉加热某些食物会爆炸?
  9. 基于透镜辅助的固态激光雷达
  10. 一对一视频app开发选择如何合适算法