2

I'm trying to create a simple labeled checkbox in SwiftUI that toggles an isChecked when the button is pressed. It's very similar to the example in Apple's Binding documentation:

import SwiftUI

struct LabeledCheckbox: View {
    var labelText: String
    @Binding var isChecked: Bool

    var checkBox: Image {
        Image(systemName: isChecked ? "checkmark.circle" : "circle")
    }

    var body: some View {
        Button(action: {
            self.isChecked.toggle()
        }) {
            HStack {
                checkBox
                Text(labelText)
            }
        }
    }
}

struct LabeledCheckbox_Previews: PreviewProvider {
    static var previews: some View {
        LabeledCheckbox(labelText: "Checkbox", isChecked: .constant(false))
    }
}

Unfortunately, when I interact with this button in "Live Preview" mode, the button action doesn't seem to actually toggle isChecked. You can view that here. I put a print(isChecked ? "checked" : "unchecked") debug statement in the action closure and observed in the console output the that isChecked was never being toggled.

I've also attempted to get LabeledCheckboxto be toggable by passing in a state variable in LabeledCheckbox_Previews. The button is still not toggable.

struct LabeledCheckbox_Previews: PreviewProvider {
    @State private static var isChecked = false

    static var previews: some View {
        LabeledCheckbox(labelText: "Checkbox", isChecked: $isChecked)
    }
}

What am I doing wrong? Any help is appreciated.

4
  • 2
    isChecked is a .constant(false), so can't be changed. Commented Mar 4, 2020 at 16:03
  • Previously, I've also created a static state variable for isChecked and and in LabeledCheckbox_Previews and pass it into the view, ala @State private static var isChecked = false. That didn't work either. Commented Mar 4, 2020 at 16:07
  • 1
    The following binding in SwiftUI Live Preview can be helpful. Commented Mar 4, 2020 at 16:19
  • 1
    You define type properties with the static keyword. don't use static for property wrapped values. Commented Mar 4, 2020 at 16:55

1 Answer 1

4

You need to provide mutable state, not a constant value. For example like this.

import SwiftUI

struct LabeledCheckbox: View {
  var labelText: String
  @Binding var isChecked: Bool

  var checkBox: Image {
    Image(systemName: isChecked ? "checkmark.circle" : "circle")
  }

  var body: some View {
    Button(action: {
      self.isChecked.toggle()
    }) {
      HStack {
        checkBox
        Text(labelText)
      }
    }
  }
}

struct ContentView: View {
  @State private var isChecked = false

  var body: some View {
    LabeledCheckbox(labelText: "Checkbox", isChecked: $isChecked)
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.