简体   繁体   中英

SwiftUI: Computed Property from reusable View not working

Using the SwiftUI framework, I created this reusable View (minus styling bells and whistles):

struct RatingView: View {
    let criteria: String
    @State var rating: Int
    
    var body: some View {
        HStack {
            Button {
                if rating > 0 {
                    rating -= 1
                }
            } label: {
                Image(systemName: "heart.slash.fill")
            }
            
            Spacer()
            
            Text("\(criteria): \(rating)")

            Spacer()
            
            Button {
                if rating < 1 {
                    rating += 1
                }
            } label: {
                Image(systemName: "heart.fill")
            }
        }
    }
}

And implemented it here (again, without the styling bells and whistles):

struct ScoringView: View {
    let story = "Story"
    let cheese = "Cheese"
    let love = "Romance"
    let actor = "In character"
    
    var storyRating = 0
    var cheesyRating = 0
    var loveRating = 0
    var actorRating = 0
    
    var roundScore: Int {
        storyRating + cheesyRating + loveRating + actorRating
    }
    
    var body: some View {                 
        VStack {
            RatingView(criteria: story, rating: storyRating)
            RatingView(criteria: cheese, rating: cheesyRating)
            RatingView(criteria: love, rating: loveRating)
            RatingView(criteria: actor, rating: actorRating)
        }
                
        Spacer()
                
        VStack {
            Text("Score this round:")
            Text("\(roundScore)")
        }
    }
}

No matter the changes I make to the rating buttons, the roundScore computed property does not change and remains at zero.

I tested the computed property in a Playground, and it works, But since I wasn't able to find anything on SO about the combo of computed properties and reusable views. so I wonder if the reusable view is messing with me.

Any thoughts?

You need something yo trigger View updates or SwiftUI doesn't know when to redraw.

Add @State

@State var storyRating = 0
@State var cheesyRating = 0
@State var loveRating = 0
@State var actorRating = 0

and remove it from RatingView

@Binding var rating: Int

@State is a source of truth and @Binding is a two-way connection.

You will also have to add $ when initializing views

RatingView(criteria: story, rating: $storyRating)
RatingView(criteria: cheese, rating: $cheesyRating)
RatingView(criteria: love, rating: $loveRating)
RatingView(criteria: actor, rating: $actorRating)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM