I'm trying to add sodas from ListView to ContentView and have that data passed on and update the view in AisleView. I'm having a lot of trouble getting my columnOne and columnTwo properties to update the AisleView correctly. I know the data is being passed to AisleView, but it isn't updating the actual view. I believe the issue is when I'm trying to initialize my columns. Any help would be appreciated. Thank you!
class Inventory {
var inventory: [Product] = [
Product(name: "Coke", price: 2.99, aisle: 1, location: 10),
Product(name: "Pepsi", price: 3.99, aisle: 1, location: 6),
Product(name: "Dr. Pepper", price: 1.99, aisle: 2, location: 8),
Product(name: "Pibb", price: 1.50, aisle: 2, location: 1)
]
}
struct ListView: View {
@State var base = Inventory()
@State var sodas: [Product] = []
var body: some View {
VStack {
ContentView(sodas: $sodas)
List {
ForEach(base.inventory) { product in
HStack {
Text(product.name)
Spacer()
Text("\(product.price, specifier: "%.2f")")
Button {
sodas.append(product)
} label: {
Image(systemName: "plus")
}
}
}
}
}
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
struct ContentView: View {
@Binding var sodas: [Product]
@State private var columnOne: [Product] = []
@State private var columnTwo: [Product] = []
init(sodas: Binding<[Product]>) {
self._sodas = sodas
self.columnOne = aisleSort(sodas: self.sodas, aisle: 1)
self.columnTwo = aisleSort(sodas: self.sodas, aisle: 2)
}
var body: some View {
VStack {
HStack(spacing: 10) {
AisleView(products: $columnOne)
AisleView(products: $columnTwo)
}
}
}
func aisleSort(sodas: [Product], aisle: Int) -> [Product] {
var sort: [Product] = []
for soda in sodas {
if soda.aisle == aisle {
sort.append(soda)
}
}
return sort
}
}
struct AisleView: View {
@Binding var products: [Product]
@State private var buttonNumber = 0
var location: [Int] {
var answer: [Int] = []
for number in products {
answer.append(number.location)
}
return answer
}
func idicator(number: Int) -> Color {
if location.contains(number) {
return Color.red
} else {
return Color.primary
}
}
var body: some View {
ZStack {
VStack(alignment: .center, spacing: 0) {
ForEach(1..<21, id: \.self) {number in
ZStack {
if location.contains(number) {
Button {
buttonNumber = number
} label: {
HStack {
Rectangle()
.foregroundColor(.red)
.frame(width: 20, height: 20)
}
}
.overlay(buttonNumber == number ? InfoView(sodas: products, number: number).offset(x: -70) : nil)
} else {
HStack {
Rectangle()
.frame(width: 20, height: 20)
.foregroundColor(idicator(number: number))
Text("\(number)")
}
}
}
}
}
}
}
}
struct InfoView: View {
@State var sodas: [Product]
@State var number: Int
var body: some View {
VStack {
ForEach(sodas) { soda in
if soda.location == number {
ZStack {
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.clear)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 10))
VStack {
Text(soda.name)
Text("$\(soda.price, specifier: "%.2f")")
}
// .font(.title)
}
.frame(width: 100, height:60)
}
}
}
}
}
struct AisleView_Previews: PreviewProvider {
static var previews: some View {
AisleView(products: ListView().$sodas)
}
}
`
In fact, you don't need aisleSort nor sodas anymore with this code. And you can simplify by removing ContentView and have directly the 2 subviens in ListView:
struct ListView: View {
@State var base = Inventory2()
// @State var sodas: [Product] = [] //
@State var columnOne: [Product] = []
@State var columnTwo: [Product] = []
var body: some View {
VStack {
// ContentView(sodas: $sodas, columnOne: $columnOne, columnTwo: $columnTwo)
HStack(spacing: 10) {
AisleView(aisleProducts: $columnOne, aisleNumber: 1)
AisleView(aisleProducts: $columnTwo, aisleNumber: 2)
}
List {
ForEach(base.inventory) { product in
HStack {
Text(product.name)
Spacer()
Text("\(product.price, specifier: "%.2f")")
Button {
// sodas.append(product)
if product.aisle == 1 {
columnOne.append(product)
} else {
columnTwo.append(product)
}
} label: {
Image(systemName: "plus")
}
}
}
}
}
}
}