Я пытаюсь сделать 5-звездочный рейтинг, используя прямоугольник и маскируя его по форме звезд. Кажется, все в порядке, когда прямоугольник имеет полную ширину (рейтинг 5 звезд), но когда это не так, выравнивание не работает.
struct FiveStarRating: View {
@State private var rating = 0
var body: some View {
stars.overlay(alignment: .leading) {
GeometryReader { proxy in
Rectangle()
.foregroundStyle(.orange)
.frame(width: CGFloat(rating) / 5 * proxy.size.width)
.animation(.bouncy, value: rating)
.allowsHitTesting(false)
.mask(stars)
}
}
}
private var stars: some View {
HStack {
ForEach(1...5, id:\.self) { i in
Image(systemName: "star.fill")
.foregroundStyle(.gray)
.font(.largeTitle)
.onTapGesture {
rating = i
}
}
}
}
}
Вы можете добавить еще один модификатор frame
, чтобы убедиться, что наложение занимает все пространство (но по-прежнему выровнено по leading
), сохраняя при этом Rectangle
ограниченным до определенного width
:
struct FiveStarRating: View {
@State private var rating = 0
var body: some View {
stars
.overlay{
GeometryReader { proxy in
Rectangle()
.foregroundStyle(.orange)
.frame(width: CGFloat(rating) / 5 * proxy.size.width)
.frame(maxWidth: .infinity, alignment: .leading) // <-- Here
.animation(.bouncy, value: rating)
.allowsHitTesting(false)
.mask(stars)
}
}
}
private var stars: some View {
HStack {
ForEach(1...5, id:\.self) { i in
Image(systemName: "star.fill")
.foregroundStyle(.gray)
.font(.largeTitle)
.onTapGesture {
rating = i
}
}
}
}
}