Reputation: 383
I am trying to assign default values to the pickers. Initially I am finding the index that matches a string ("Tesco") but when this works I will replace the string with the product.product_name
that is passed into the ProductDetail
struct. If I remove the init()
method (and uncomment the relevant variables) then the error disappears and it works as normal. I have tried moving the var product = Product_
declaration into the init()
but that causes different errors. I feel I am just trying every combination without knowing why they aren't working. I am sure at some point it'll work but I won't know why.
I am getting a Argument passed to call that takes no arguments
. Error occurs in the ProductDetail_Previews
struct.
struct ProductDetail: View {
// Define product as a constant that takes on the values for one specific product
var product: Product_
// Define a constant for the available brands
//let all_brands = ["Asda", "Tesco", "Sainsbury's", "M&S"]
@State var all_brands: [String]
//State var currentBrand = 2
@State var currentBrand: Int
init(){
self.all_brands = ["Asda", "Tesco", "Sainsbury's", "M&S"]
// Find the first index in the list of all_brands where the string is present
self.currentBrand = all_brands.firstIndex(of: "Tesco") ?? 0
}
var body: some View {
//This is the main stack that contains everything
VStack(alignment: .leading){
//Create a form to hold the Picker(s)
Form{
Text(product.product_name)
.fontWeight(.bold)
.font(.title)
.padding()
HStack{
Text("EAN Code:")
Text(product.code).padding()
}
// Picker for Brand
Picker(selection: $currentBrand, label: Text("Brand")){
ForEach(0 ..< all_brands.count){
Text(self.all_brands[$0])
}}
}
}
}
}//Closing bracket for main VStack
struct ProductDetail_Previews: PreviewProvider {
static var previews: some View {
ProductDetail(product: products[2])
}
}
Thanks.
Upvotes: 0
Views: 271
Reputation: 285270
There is an inconsistency. The init
method takes no arguments (that's what the error says) but product
is not being initialized.
As the initial values of the @State
variables are constants anyway and you cannot initialize @State
properties this way I'd recommend to omit the init method and assign the values literally.
struct ProductDetail: View {
// Define product as a constant that takes on the values for one specific product
var product: Product_
@State private var all_brands = ["Asda", "Tesco", "Sainsbury's", "M&S"]
@State private var currentBrand = 1
var body: some View { ...
And please stop using those underscore characters and snake_case names. That's pretty unswifty
Upvotes: 1
Reputation: 54785
Your initialiser is wrong, it should take a Product
input argument.
When initialising a State
based on input arguments, you need to assign to the State
property by accessing it using the _
prefix and assigning State(initialValue:)
.
struct ProductDetail: View {
private let product: Product
@State private var allBrands: [String]
//State var currentBrand = 2
@State private var currentBrand: Int
init(product: Product) {
self.product = product
let brands = ["Asda", "Tesco", "Sainsbury's", "M&S"]
self._allBrands = State(initialValue: brands)
// Find the first index in the list of all_brands where the string is present
self._currentBrand = State(initialValue: brands.firstIndex(of: "Tesco") ?? 0)
}
Unrelated to your question, but all @State
s should be declared as private
, since they should never be mutated from outside the view. Also, you should conform to the Swift naming convention, which is lowerCamelCase for variable names and UpperCamelCase for type names.
Upvotes: 2