0

I'm trying to clone this view:

enter image description here

Unfortunately I have a problem with the Geometry Reader (I guess). It's making a bigger frame then the actual rectangle (see blue area):

enter image description here

Same applies to the stars as well:

enter image description here

Can you point me to my issue? Is something nested wrong? I also tried to include Spacer()but this didn't resolve it.

My Code looks like this:

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()
    }
}

Many Thanks!

Ken White
  • 123,280
  • 14
  • 225
  • 444
SwiftUIRookie
  • 591
  • 7
  • 16

1 Answers1

1

test this

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
    }
}
Simone Pistecchia
  • 2,746
  • 3
  • 18
  • 30