使用SwiftUI搭建一个简易书籍阅读App,做一个爱读书的人~
项目背景
自修道以来,每天晚上都会在群里和师兄弟们一起诵读经书,已然成为一种习惯。
不过总是带着纸质的书籍总该是不方便,网上又没有我们诵读的版本,于是想着自己搭建一个吧。
说干就干。
项目搭建
首先,创建一个新的SwiftUI
项目,命名为ConfucianClassics
。
模型搭建
首先,我们先创建一个数据模型,我们命名为Book
。
struct Book:Identifiable { var id = UUID() var title: String var content: String }
上述代码中,我们创建了一个Book
结构体,遵循Identifiable
协议。
然后我们声明了几个变量:id
作为唯一标识符,title
为标题,content
为内容。
完成后,我们来创建一些示例数据,示例:
private var books = [ Book(title: "第一章:论德", content: "上德不德,是以有德。下德不失德;是以无德。上德无为而无以为也。上仁为之,而无以为也;上义为之,而有以为也。上礼为之,而莫之应也,则攘臂而乃之。故失道而后德,失德而后仁,失仁而后义,失义而后礼。夫礼者,忠信之泊也,而乱之首也。前识者,道之华也,而愚之首也。是以大丈夫居其厚,而不居其泊,居其实,而不居其华。故去皮取此。"), Book(title: "第二章:得一", content: "昔之得一者,天得一以清,地得一以宁,神得一以灵,浴得一以盈,侯王得一而以为天下正。其至之也。谓天毋已清将恐裂;谓地毋已宁将恐发;谓神毋已灵将愁歇;谓浴毋已盈将恐竭;谓侯王毋已贵以高将恐蹶。故必贵而以贱为本,必高矣而以下为基。夫是以侯王自谓孤、寡、不穀,此其贱之为本与?非也!故致数与无与。是故不欲禄禄若玉,硌硌若石。"), Book(title: "第三章:闻道", content: "上士闻道,堇能行之;中士闻道,若存若亡;下士闻道,大笑之,弗笑不足以为道。是以建言有之日:明道如费,进道如退,夷道如类;上德如浴,大白如辱,广德如不足。建德如输,质真如渝,大方无隅;大器晚成,大音希声,大象无形,道隐无名。夫唯道,善始且善成。"), Book(title: "第四章:反复", content: "反也者,道之动也;弱也者,道之用也。天下之物生于有,有生于无。"), Book(title: "第五章:中和", content: "道生一,一生二,二生三,三生万物。万物负阴而抱阳,中气以为和。天下之所恶,唯孤、寡、不穀,而王公以为自名也。勿或损之而益,或益之而损。觐殷死,议而教人。故强良者不得死,我将以为学父。"), Book(title: "第六章:至柔", content: "天下之至柔,驰骋于天下之至坚。无有入于无间。吾是以知无为之有益。不言之教,无为之益,天下希能及之矣。"), Book(title: "第七章:立戒", content: "名与身孰亲?身与货孰多?得与亡孰病?甚爱必大费,多藏必厚亡。故知足不辱,知止不殆,可以长久。"), Book(title: "第八章:请靓", content: "大成若缺,其用不敝;大盈若冲,其用不穷。大直若诎,大巧若拙,大赢如绌。躁胜寒,靓胜炅。请靓可以为天下正。"), Book(title: "第九章:知足", content: "天下有道,却走马以粪。天下无道,戎马生于郊。罪莫大于可欲,祸莫大于不知足,咎莫僭于欲得。故知足之足,恒足矣。"), Book(title: "第十章:知天下", content: "不出于户,以知天下。不窥于牖,以知天道。其出也弥远,其知也弥少。是以圣人,不行而知,不见而名,弗为而成。"), ]
就此,数据部分我们就准备好了。
页面样式
页面部分可以做的很简答,我们使用List
列表来构建内容,示例:
NavigationView { List(books) { book in Text(book.title) }.navigationBarTitle("德道经") }
上述代码中,我们使用List
构建了一个列表,遍历books
示例数据数组中的数据,内容部分我们使用Text
文字作为列表的内容。
另外,因为后面需要基于顶部导航栏进行跳转,我们还使用了NavigationView
构建一个顶部导航栏视图,我们加了一个标题。
详情页
下一步,我们需要构建点击对应章节的内容,进入到章节的详情页。
我们构建一个新的视图,命名为DetailView
。
// 详情页面 struct DetailView: View { var book: Book var body: some View { VStack { Text(book.content) .font(.system(size: 17)) .lineSpacing(10) .padding() Spacer() }.navigationBarTitle(book.title, displayMode: .inline) } }
上述代码中,我们创建了一个DetailView
视图。
在视图中,我们首先声明了一个类型为Book
变量book
,这样在我们传递数据的时候,就可以给book
传递数值。
主要内容部分,我们使用Text
构建内容,使用font
修饰符设置文字字号,使用lineSpacing
设置文字字间距,使用padding
给整个文字展示位置加边距。
最后使用navigationBarTitle
设置了该页面的标题,展示方式为inline
居中。
页面跳转
完成后,最后我们来做从ContentView
视图跳转到DetailView
视图。
NavigationView { List(books) { book in NavigationLink(destination: DetailView(book: book)) { Text(book.title) } }.navigationBarTitle("德道经") }
上述代码中,我们使用NavigationLink
基于导航栏的跳转方式,从ContentView
视图跳转到DetailView
视图,并且从ContentView
视图把book
数组数据源带入到DetailView
视图中的book
数组。
这样,我们就完成了页面的跳转和数据的传递。