#swiftui #bar-chart #geometryreader #viewbuilder
Вопрос:
Я пытаюсь клонировать этот вид:
К сожалению, у меня проблема с читателем геометрии (я думаю). Это делает рамку больше, чем сам прямоугольник (см. синюю область).:
То же самое относится и к звездам:
Можете ли вы указать мне на мою проблему? Что-то не так с вложением? Я также попытался включить 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)-gt;some View{ HStack{ HStack{ ForEach(1..lt;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()-gt;CGFloat{ let max = ratings.max { first, second in return second.ratingCount gt; first.ratingCount } return max?.ratingCount ?? 0 } } struct RatingGraphView_Previews: PreviewProvider { static var previews: some View { RatingGraphView() } }
Большое Спасибо!
Ответ №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: 0){ ForEach(ratings){rating in RatingView(rating: rating) } } .frame(height: 100) } @ViewBuilder func RatingView(rating: Ratings)-gt;some View{ GeometryReader{proxy in HStack { HStack{ Spacer() ForEach(1..lt;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()-gt;CGFloat{ let max = ratings.max { first, second in return second.ratingCount gt; first.ratingCount } return max?.ratingCount ?? 0 } }