Home > OS >  Reset View on Button Click SwiftUI
Reset View on Button Click SwiftUI

Time:04-20

I would like to reset a View when a button like "Clear" or "Reset" is tapped. This is my current progress:

struct Cell: Hashable {
   let value: Int
}

struct CellView: View {
  var cell: Cell
  @State private var isDisabled = false

  var body: some View {
      Button {
          isDisabled = true
      } label: {
          Text("\(cell.value)")
              .frame(width: 100, height: 100)
      }.disabled(isDisabled)
          .border(Color.black)
  }

  func toggleDisabled() {
      isDisabled = false
  }
}

The user is only supposed to be able to click on the button once unless they reset the board. The initial idea was to keep track of the CellViews so that I could then toggle the state using toggleDisabled() like so

struct ContentView: View {
  var cellViews = [
    CellView(cell: Cell(value: 1)), 
    CellView(cell: Cell(value: 2))
  ]

  var body: some View {
    cellViews[0]
    cellViews[1]

    Button("Clear") {
      cellViews.forEach{ $0.toggleDisabled() }
    }
  }
}

but I am running into trouble making this happen.

I considered storing the isDisabled in the Cell and making CellView have a Binding to it but that wasn't possible either. What is the correct approach to achieve this?

CodePudding user response:

you could try this approach using a ObservableObject model to keep track of your Cell state. For example:

class CellViewModel: ObservableObject {
    @Published var cells = [Cell]()
    
    func resetAll() {
        for i in cells.indices {
            cells[i].isDisabled = false
        }
    }
    
}

struct CellView: View {
    @Binding var cell: Cell
    
    var body: some View {
        Button {
            cell.isDisabled = true
        } label: {
            Text("\(cell.value)").frame(width: 100, height: 100)
        }.disabled(cell.isDisabled)
            .border(Color.black)
    }
}

struct ContentView: View {
    @StateObject var cellModel = CellViewModel()
    
    var body: some View {
        VStack {
            List {
                ForEach($cellModel.cells) { $cell in
                   CellView(cell: $cell)
                }
            }
            Button("Reset all") {
                cellModel.resetAll()
            }
        }
        .onAppear {
            cellModel.cells.append(Cell(value: 1))
            cellModel.cells.append(Cell(value: 2))
        }
    }
}

struct Cell: Identifiable, Hashable {
    let id = UUID()
    let value: Int
    var isDisabled = false
}

CodePudding user response:

What you considered is correct. To do this make cells @State. Move isDisabled into Cell. Pass a binding to the cell into CellView.

  • Related