Пользовательский просмотр рейтинга с вложенными H и VStacks приводит к странному кадру

#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  } }