使用SwiftUI搭建一个简易书籍阅读App,做一个爱读书的人~

1,865 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

在本章中,你将学会使用SwiftUI搭建一个简易书籍阅读App

项目背景

自修道以来,每天晚上都会在群里和师兄弟们一起诵读经书,已然成为一种习惯。

不过总是带着纸质的书籍总该是不方便,网上又没有我们诵读的版本,于是想着自己搭建一个吧。

说干就干。

项目搭建

首先,创建一个新的SwiftUI项目,命名为ConfucianClassics

1.png

模型搭建

首先,我们先创建一个数据模型,我们命名为Book

struct Book:Identifiable {
    var id = UUID()
    var title: String
    var content: String
}

2.png

上述代码中,我们创建了一个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("德道经")
}

4.png

上述代码中,我们使用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)
    }
}

5.png

上述代码中,我们创建了一个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数组。

这样,我们就完成了页面的跳转和数据的传递。

项目展示

6.gif

恭喜你,完成了整个项目的全部内容!

快来动手试试吧。

如果本专栏对你有帮助,不妨点赞、评论、关注~