带有嵌套 H 和 VStacks 的自定义评级视图导致奇怪的框架
Custom Rating view with nested H and VStacks leads to weird frame
我正在尝试复制此视图:
不幸的是我的几何学有问题Reader(我猜)。它正在制作比实际矩形更大的框架(见蓝色区域):
同样适用于星星:
你能指出我的问题吗?嵌套有问题吗?我也尝试包括 Spacer()
但这并没有解决问题。
我的代码如下所示:
import SwiftUI
struct Ratings: Identifiable {
var id = UUID().uuidString
var ratingCount: CGFloat
var starCount: Int
}
var userRatings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
struct RatingGraphView: View {
var ratings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
var body: some View {
VStack(spacing: 10){
ForEach(ratings){rating in
RatingView(rating: rating)
}
}
.frame(height: 200)
}
@ViewBuilder
func RatingView(rating: Ratings)->some View{
HStack{
HStack{
ForEach(1..<rating.starCount+1){ star in
Image(systemName: "star")
.resizable()
.aspectRatio(contentMode:.fit)
.frame(height:15)
.scaledToFit()
.padding(.bottom)
}
}
.frame(maxWidth:.infinity, alignment: .trailing)
HStack{
VStack{
GeometryReader{proxy in
let size = proxy.size
RoundedRectangle(cornerRadius: 6)
.fill(Color.blue)
.frame(width: (rating.ratingCount / getMax()) * (size.width), height: 15)
}
}
}
}
.padding(.trailing)
}
func getMax()->CGFloat{
let max = ratings.max { first, second in
return second.ratingCount > first.ratingCount
}
return max?.ratingCount ?? 0
}
}
struct RatingGraphView_Previews: PreviewProvider {
static var previews: some View {
RatingGraphView()
}
}
非常感谢!
测试这个
struct RatingGraphView: View {
var ratings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
var body: some View {
VStack(spacing: 0){
ForEach(ratings){rating in
RatingView(rating: rating)
}
}
.frame(height: 100)
}
@ViewBuilder
func RatingView(rating: Ratings)->some View{
GeometryReader{proxy in
HStack {
HStack{
Spacer()
ForEach(1..<rating.starCount+1){ star in
Image(systemName: "star")
.resizable()
.aspectRatio(contentMode:.fit)
.frame(height:15)
.scaledToFit()
//.padding(.bottom)
}
}
.frame(width:proxy.size.width/2.5)
let size = proxy.size
RoundedRectangle(cornerRadius: 6)
.fill(Color.blue)
.frame(width: (rating.ratingCount / getMax()) * (proxy.size.width * 1.5/3), height: 15)
}
}
}
func getMax()->CGFloat{
let max = ratings.max { first, second in
return second.ratingCount > first.ratingCount
}
return max?.ratingCount ?? 0
}
}
我正在尝试复制此视图:
不幸的是我的几何学有问题Reader(我猜)。它正在制作比实际矩形更大的框架(见蓝色区域):
同样适用于星星:
你能指出我的问题吗?嵌套有问题吗?我也尝试包括 Spacer()
但这并没有解决问题。
我的代码如下所示:
import SwiftUI
struct Ratings: Identifiable {
var id = UUID().uuidString
var ratingCount: CGFloat
var starCount: Int
}
var userRatings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
struct RatingGraphView: View {
var ratings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
var body: some View {
VStack(spacing: 10){
ForEach(ratings){rating in
RatingView(rating: rating)
}
}
.frame(height: 200)
}
@ViewBuilder
func RatingView(rating: Ratings)->some View{
HStack{
HStack{
ForEach(1..<rating.starCount+1){ star in
Image(systemName: "star")
.resizable()
.aspectRatio(contentMode:.fit)
.frame(height:15)
.scaledToFit()
.padding(.bottom)
}
}
.frame(maxWidth:.infinity, alignment: .trailing)
HStack{
VStack{
GeometryReader{proxy in
let size = proxy.size
RoundedRectangle(cornerRadius: 6)
.fill(Color.blue)
.frame(width: (rating.ratingCount / getMax()) * (size.width), height: 15)
}
}
}
}
.padding(.trailing)
}
func getMax()->CGFloat{
let max = ratings.max { first, second in
return second.ratingCount > first.ratingCount
}
return max?.ratingCount ?? 0
}
}
struct RatingGraphView_Previews: PreviewProvider {
static var previews: some View {
RatingGraphView()
}
}
非常感谢!
测试这个
struct RatingGraphView: View {
var ratings: [Ratings] = [
Ratings(ratingCount: 130, starCount: 5),
Ratings(ratingCount: 90, starCount: 4),
Ratings(ratingCount: 25, starCount: 3),
Ratings(ratingCount: 20, starCount: 2),
Ratings(ratingCount: 3, starCount: 1)
]
var body: some View {
VStack(spacing: 0){
ForEach(ratings){rating in
RatingView(rating: rating)
}
}
.frame(height: 100)
}
@ViewBuilder
func RatingView(rating: Ratings)->some View{
GeometryReader{proxy in
HStack {
HStack{
Spacer()
ForEach(1..<rating.starCount+1){ star in
Image(systemName: "star")
.resizable()
.aspectRatio(contentMode:.fit)
.frame(height:15)
.scaledToFit()
//.padding(.bottom)
}
}
.frame(width:proxy.size.width/2.5)
let size = proxy.size
RoundedRectangle(cornerRadius: 6)
.fill(Color.blue)
.frame(width: (rating.ratingCount / getMax()) * (proxy.size.width * 1.5/3), height: 15)
}
}
}
func getMax()->CGFloat{
let max = ratings.max { first, second in
return second.ratingCount > first.ratingCount
}
return max?.ratingCount ?? 0
}
}