译自 www.hackingwithswift.com/books/ios-s…
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀
显示图书细节
当用户点击ContentView里的一本图书时,我们要呈现一个细节视图,展示更多的信息 —— 书的流派,简单的评价,等等。我们会重用RatingView,通过自定义,你会发现 SwiftUI 有多么灵活。
为了这个界面更有趣,我们要在应用中添加一些表示不同类别的 artwork。我从 Unsplash 挑选了一些 artwork,把它们放在 project11-files 文件夹下 —— 如果你已经下载好了,可以直接拖到你的 asset catalog。
Unsplash 对于图片的使用,有商业用途和非商业用途的不同 license。我添加的图片是由 Ryan Wallace, Eugene Triguba,Jamie Street,Alvaro Serrano,Joao Silas,David Dilbert 和 Casey Horner 创作的 —— 如果你需要,可以从unsplash.com获取原始图片。
接下来,创建一个叫 “DetailView” 的新 SwiftUI 视图。它只需要一个属性,即要显示的图书,添加下面这行:
let book: Book即便只有这一行,就足以使预览代码无法编译。之前这种问题很容易修复,因为我们可以传入一个例子对象,但是当我们引入 Core Data 之后,事情稍微复杂了:创建一个新的图书对象同时也意味着我们需要有一个 managed object context。
为了解决这个问题,我们需要更新预览的代码,创建一个临时的 managed object context,然后用它来创建图书对象。
创建 managed object context 意味着我们需要引入 Core Data。把下面这行添加到 DetailView.swift 顶部,在之前的import语句之前:
import CoreData对于预览代码,把之前的代码替换成下面这样:
struct DetailView_Previews: PreviewProvider {
static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
static var previews: some View {
let book = Book(context: moc)
book.title = "Test book"
book.author = "Test author"
book.genre = "Fantasy"
book.rating = 4
book.review = "This was a great book; I really enjoyed it."
return NavigationView {
DetailView(book: book)
}
}
}如你所见,创建一个 managed object context 包括告知系统我们想要的 concurrency type。它的意思是“你想要在哪个线程访问你的数据”。对于我们的例子,使用主队列 —— 这是应用启动时采用的线程 —— 对于我们的例子足够了。
现在把注意力回到更有趣的问题:设计视图本身。我们首先把分类图片和流派放进一个ZStack,以便可以将一个叠在另一个上面。我们需要用到GeometryReader,以确保图片不会占据太多空间。我选取一些我认为不错的样式,但你自己也可以尝试任何你想要的样式。
把当前的body属性替换成下面这样:
GeometryReader { geometry in
VStack {
ZStack(alignment: .bottomTrailing) {
Image(self.book.genre ?? "Fantasy")
.frame(maxWidth: geometry.size.width)
Text(self.book.genre?.uppercased() ?? "FANTASY")
.font(.caption)
.fontWeight(.black)
.padding(8)
.foregroundColor(.white)
.background(Color.black.opacity(0.75))
.clipShape(Capsule())
.offset(x: -5, y: -5)
}
}
}
.navigationBarTitle(Text(book.title ?? "Unknown Book"), displayMode: .inline)上面的代码把流派名放在ZStack的右下角,并且使用了一个背景色,粗体字,以及一些留白以凸显自己。
在ZStack下方,我们要添加 review 和 rating,再加上一个 spacer ,以便所有的元素被推到视图的顶部。我们不希望用户可以这个界面调整评级,因此我们将使用另一个常量绑定,把评级视图编程只读的视图。更棒的是,由于我们采用 SF Symbols 来创建评级图像,我们可以简单地使用一个font()modifier 来放大它们,以充分利用给到我们的空间。
把下面这些视图添加到之前的ZStack下方:
Text(self.book.author ?? "Unknown author")
.font(.title)
.foregroundColor(.secondary)
Text(self.book.review ?? "No review")
.padding()
RatingView(rating: .constant(Int(self.book.rating)))
.font(.largeTitle)
Spacer()这样一来就完成了DetailView,我们回到 ContentView.swift ,修改导航链接,让它指向正确的东西:
NavigationLink(destination: DetailView(book: book)) {现在,再次运行应用,你应该能够点击任意图书,然后进入一个显示它们细节的新视图。
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~
