UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Cannot assign to property: 'user' is a get-only property

Forums > SwiftUI

I am very new to swiftui and coding all together and cannot not figure this one out. I simply want to create a button on my home tab that changes "selectedtc" (Selected team color) to the value that is set to that team. that way I can change all text and image colors to the color that the user selects througout all of my screens. on the button, the title is listed as team 1. the action is set to change selectedtc to .blue but it states "Cannot assign to property: 'user' is a get-only property"

Home tab code:

struct User {
var selectedtc: Color
}

class ContentViewModel: ObservableObject {
@Published var user: User

init() {
    self.user = User(
        selectedtc: .red)

}
}

struct HomeTab: View {
@StateObject var viewModel = ContentViewModel()

private var user: User {
    return viewModel.user
}

var body: some View {
    VStack {

        Button("Team 1") {
            user.selectedtc = Color (.blue)

        }
        Text(verbatim: "Hello")

    }
        .foregroundColor(user.selectedtc)

}
}

#Preview {
HomeTab()
}

   

@Obelix thanks! my fault! I fixed it!

   

@Brandon wants to be more observant.

I ...snip... cannot not figure this one out.

Welcome to HackingWithSwiftUI

Please follow the course! Watch the videos. Type out all the examples. And complete the assignments.

In your code above, you're using older protocols (eg ObservableObject, @Published) for the observation framework. I suppose I could teach you why your code isn't working but maybe it would be teaching you how to add horseshoes to your farm animals when everyone else has moved on to gas-powered tractors. Maybe that's not a great analogy, but the newer syntax is a bit easer.

Our host @twoStraws has a fantastic progression of lessons that will help you understand concepts in bite-sized pieces. If you're not following the progam, you're missing out on a nice treat. Plus, you'll end up in a bad alley (like your code above) and bump your head wondering why your (old? malformed?) code isn't working. Follow the program and you'll put the pieces together.

Sample Code

Add this code to a new project and see if this works?

struct ColorChangeView: View {
    // Any changes to this object
    // will be broadcast to all subordinate views
    // which reference someTeam
    @State private var someTeam = Team()

    var body: some View {
        VStack {
            Text(someTeam.teamName).font(.largeTitle)
            ColorSample(teamTitle: "Home Team Color", theColor: someTeam.homeColor)
            ColorSample(teamTitle: "Away Team Color", theColor: someTeam.awayColor)
                .padding(.bottom)
            LogoView(teamLogo: someTeam) // <-- Pass in an observed object!
            Spacer()
            // =========== Pick the Colors ====================
            VStack{
                Text("Pick Your Team Colors").font(.subheadline)
                ColorPicker("Home Color", selection: $someTeam.homeColor )
                ColorPicker("Away Color", selection: $someTeam.awayColor )
            }
        }
        .padding()
        .onAppear { someTeam.teamName = "Swifties"}
    }
}

// What does this struct do?
// It's a small view with one purpose.
// SHOW a rectangle with the appropriate color and label
struct ColorSample: View {
    var teamTitle: String
    var theColor:  Color
    var body:      some View {
        Rectangle()
            .frame(height: 120)
            .foregroundColor(theColor)
            .overlay { Text(teamTitle) }
    }
}

// When you tap a circle why does the large
// rectangle change color to indigo?
struct LogoView: View {
    var teamLogo: Team // pass this in

    var body: some View {
        VStack {
            Text("Tap the Icons to reset.")
            HStack{
                Circle()
                    .frame(width: 50, height: 50)
                    .foregroundColor(teamLogo.homeColor)
                    .overlay { Image(systemName: "bird")}
                // HOW? How does this get back up to the main screen?
                    .onTapGesture { teamLogo.homeColor = .indigo }
                Circle()
                    .frame(width: 50, height: 50)
                    .foregroundColor(teamLogo.awayColor)
                    .overlay { Image(systemName: "bird")}
                    .onTapGesture { teamLogo.awayColor = .indigo }
            }
        }
    }
}

// ALERT!!!  Tell SwiftUI to watch this class closely.
// We want to alert all objects which reference this class
// when any changes are made to its varibles.
@Observable
class Team {
    var teamName = ""
    var homeColor = Color.teal
    var awayColor = Color.blue

    // No initializer necessary because
    // all internal parameters have default values.
}

Keep Coding

Please return here and let us know how you solved your issue. Plus, we'd like to know what day of the 100 Day programme you're on.

One last thing, there is no need to abbreviate your variables. This is totally unnecessary!

"selectedtc" (Selected team color)

Instead, simply write out clear, long variable names describing what you're storing! Xcode has great features to autocomplete variable names as you type them out. Future you will be thankful that you took the time to spell out your variables.

   

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.