I am following Stanfords’ CS193p Developing Apps for iOS online course.
I am using Xcode 11.5. (I didn’t update because that’s the version the course instructor (Paul Heagarty) is using.)
I’m trying to do the Assignment 3 (Set Game). I know my code is probably poorly written in many places, but I am going to refine it later, right now I am just trying to make it work with no errors.
The error I currently can not fix is this:
var shading: SetGameModel.Card.Shading = card.shading //Error: Cannot use instance member 'card' within property initializer; property initializers run before 'self' is available
And here is full View code:
If you also need ViewModel, Model or some other files to help me fix it, let me know 🙂
Please try to help me fix it in some way, that I will understand as a beginner 🙏
//
// SetGameView.swift
// TheSetGame
//
import SwiftUI
struct SetGameView: View {
@ObservedObject var viewModel: SetGameViewModel
var body: some View {
Grid(viewModel.cards) { card in
CardView(card: card, shading: .solid).onTapGesture {
self.viewModel.choose(card: card)
}
}
.padding()
.foregroundColor(Color.orange)
}
}
struct CardView: View {
var card: SetGameModel.Card
// Shape features (numberOfShapes, shape, shading, color):
var numberOfShapes: Int {
switch card.numberOfShapes {
case .one:
return 1
case .two:
return 2
case .three:
return 3
}
}
var shading: SetGameModel.Card.Shading = card.shading //Error: Cannot use instance member 'card' within property initializer; property initializers run before 'self' is available
var isFilled: Bool { shading == .solid ? true : false }
var isStriped: Bool { shading == .striped ? true : false }
var color: Color {
switch card.color {
case .green:
return Color.green
case .purple:
return Color.purple
case .red:
return Color.red
}
}
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 10.0).fill(Color.white)
RoundedRectangle(cornerRadius: 10.0)
.stroke(lineWidth: card.isChosen ? 6 : 3)
.foregroundColor(card.isChosen ? Color.red : Color.orange)
VStack {
ForEach(0..<numberOfShapes) { index in
if self.card.shape == .diamond {
Diamond()//.scale(0.75)
}
if self.card.shape == .squiggle {
Rectangle()//.scale(0.75)
}
if self.card.shape == .oval {
Ellipse()//.scale(0.75)
}
}
}
.foregroundColor(self.color)
.padding()
}
.aspectRatio(2/3, contentMode: .fit)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
SetGameView(viewModel: SetGameViewModel())
}
}
3
Answers
This is going to sound a bit existential, but the compiler is complaining because you are trying to set
shading
to a value that does not exist yet. When you first set the values of your variables in the View, they do not actually exist. You are telling the compiler what they are going to be, but the compiler insists that the thing that you have said the variable will be actually exists.There are ways around this, such as George E. suggesting a lazy var. I don’t want to go down that route as that is beyond a beginner. For your purposes just know, when you define a variable, it must be give an actual value. The compiler won’t complain about
var x = 1
because it knows what 1 is, and it already exists.Your exact error says you can’t use the instance
card
because it has not been initialized at the time you are trying to use it. In other words, it has no value when you are trying to assign it, ascard.shading
toshading
.Now, that being said, why do you need shading at all? Isn’t the shading you want always going to be
card.shading
? Rather than make a separate variable, just use what you have. Learn to love dot notation and keep it simple.The last thing to consider, outside of your original question, is that you have a view without any State variables. Your compiler will complain at runtime if you try to change a variable that is not marked @State. What you have created is a fixed view, not one that can change or update.
If you have dependency of preperties initialization you need to do this in
init
.Replace those lines
To
Read this docs for clearly understanding why you cannot using
card.shading
.https://docs.swift.org/swift-book/LanguageGuide/Initialization.html