[SwiftUI 100天] Bookworm-part5 自定义评星组件

译自www.hackingwithswift.com/books/ios-s…
更多内容,欢迎重视大众号 「Swift花园」
喜欢文章?不如来个 ➕三连?重视专栏,重视我

增加自定义评星组D s + } m

SwiftUI 使得创立自定义 UI 组件变得十分容易,因为它们基P j g本上便是一些暴露了某些@Binding给咱们的视图。

为了说明这一点,咱们要构建一个星级点评视图,可以让用户经过点击图片挑选 1 分 到 5 分。虽然在咱们的事例中,只需要很简单的完成就能工作,不过为了让这个控件也能适用于其他地方,咱们需要为它增加一些灵活性。这意味着咱们需要设计几个自定义特点:

  • 评级的标签(默许:空字符串)
  • 最大等级评定(默许:5)
  • ( – K k o F $ } 8亮星星和未点亮星星的图片(默j K e a许:S W g Qnil 作为未点亮的图片,一个填充的星星作为点亮的图片;假如咱们发现未点亮用的也是 nil,那咱们对其也适用点亮的图片)
  • 点亮和未点亮的颜色(默许:点亮用黄色,未点亮用灰色)

咱们还需要一个额外的特点存储@Binding整数,以便咱们报告用户挑选的星级。

创立一个新的 SwiftUI 视图,取l F b i U S !名 “RatingView”,增加下面这些特点:

@Binding var rating: Int
var label = 5 P i""
va* m  - . Q _ ar maximumRating = 5
var offImage: Image?
var onImageJ _ , R = Image(systemName:u - o b T p , j _ "star.fill")
var offColor = Color.gray
var onColor = Color.yellow

在咱们填充body特点之前,请先测验编译代码 —— 你会发现编译失败,因为RatingView_Previews结构体没有为rating传入Binding

SwiftUI 对此有一个专门的简单解决方案,称为常量 bindings。它们是一` E i L M x些拥有固定值的 bindings ,一方面意味着它们不能在 UI 中改动,同时也意味着咱们可以十分方便地创立它们 —— 关于预览的场景十分适用。

p1 t Hre* @ . I 8views特点替换成下面这样:

stV b w D ( Latic var pre? W 4 J X q y o _views: some View {
RatingView(rating: .conf 4 R - ) + Z sstant(4))
}

现在让咱们回到body特点。这里头会有一个HStack,包含要显现的标签,加上足够多的星星 —— 不过,咱们可以挑选自己的图片,当然不一定必须是星星。

给星星挑选图片的逻辑十分简单,但将它们拆分到自己的办法可以降z r j ) z低代码的复杂度。逻辑如下:

  • 假如索引大于当前评级,假如未r I }点亮的图画存在,回来未点亮的图画,否则回来点亮的图画。
  • 假如传索引小于等于当前评级,回来点亮的图画。

咱们可以把这个8 c @ k h Q 2 | )逻辑封装成一个办法,把下面的代码增加到Ratinq y | = E p 6 % 5gView

func image(for number: Int) -> Image {
if number > ratin, [ } 3 i 1g {
retur. p 7 & [ 8 on offImage ?? onImage
} else {
return onImage
}
}

现在,完成body特点变得令人惊讶的简单。假如标签有文本,则使用为其创立文本M $ % {视图,然后使用ForEach遍历 1 到最大等级,G r a ) I 0 D R /然后调用重复调用image(for:)。取决于评级,咱们还要使用一个前. Y U X ? M 7 =景色,并M O 1 ?且增加点击手势,以支持选定等级。

body特点替换成下面这样:

HStack {
if label.isEmpty == false {
Text(labG z G c { B C } |el)
}t i ! 8 Z f 7 K
ForEach(1...maximumRating) { number in
sm , j o 3 ] Ielf.image(for: number)
.foregroundColor(num; h ; Z d )ber > self.rating ? self.offColor : self.onColor)# U o h Q 5 M
.onTapGesture {U ~ o y
self.rating = number
}
}
}

这样一来咱们的评级视图就完成了,把它放回9 v {咱们的AddBookView,用下面的代码B m m e * +替换第二个阶段本来的代码:

Section {
RatingView(rating: $rating)
TextField("Write a review", text:/ E ? X } $review)
}

所需的代码就这些 —— 咱们的默许值是合理的,所以视觉效果看起来很不错。你也不必再点f ; q o G O | 击进入挑选器视图中取挑选星级,这些星星评级视图看起来更自然,也更常用。

[SwiftUI 100天] Bookworm-part5 自定义评星组件