How to create CheckBox in SwiftUI

SwiftUI Multiple CheckBox
  1. Here we gonna create a List In SwiftUI with checkboxes in row items, where user can select Multiple checkboxes And the data is managed through ObservedObject
  2. There is a Button Called “Get Selected Values” on click of it, it will fetch the selected row of the list & print it on debugger
  3. In this example we will be using Mock data for dataSets, In your case you can use RealDatasets from WebServer

Let’s start with code –

1. Create a Json File for Mock Data

Xcode->New->File->Strings. Rename it to Movies.json

[
    {
        "title": "Bajrangi Bhaijaan",
    },
    {
        "title": "Kuch Kuch Hota he",
    },
    {
        "title": "Americal PIE",
    },
    {
        "title": "Hang over Part 3",
    },
    {
        "title": "Edge of Tomorrow",
    },
    {
        "title": "Blade Runner 2049",
    },
    {
        "title": "Inception",
    },
    {
        "title": "The Matrix",
    }
]
2. Add MovieEntity.swift for Model

Create a struct which conforms to codable & holds dataSets of JSON file

struct MovieEntity {
    let title: String
    var isFavorite = false
}

extension MovieEntity: Decodable {
    enum CodingKeys: String, CodingKey {
        case title
    }
}

We will be using ObservableObject which can be used as dataSource for the List

class MoviesModel: ObservableObject {
    @Published var data: [MovieEntity] = []
    init() {
        self.data = MockDataJSON.movies
    }
}
3. Create .swift file MockDataJSON.swift

We will be reading the data from Json & feed into the MovieEntity with use of JSONDecoder

import Foundation
struct MockDataJSON {
    static var movies: [MovieEntity] = {
        let url = Bundle.main.url(forResource: "Movies", withExtension: "json")!
        let data = try! Data(contentsOf: url)
        let decoder = JSONDecoder()
        return try! decoder.decode([MovieEntity].self, from: data)
    }()
}
4. CheckBox class creation

Create a checkbox class which has Image Image(systemName: isChecked ? "checkmark.square.fill" : "square") So based on isChecked we are selected Checkbox image.

import SwiftUI

struct CheckBoxView: View {
    
    let isChecked: Bool;
    
    var body: some View {
        Image(systemName: isChecked ? "checkmark.square.fill" : "square")
            .foregroundColor(isChecked ? Color(UIColor.systemBlue) : Color.secondary)
    }
}

struct CheckBoxView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            CheckBoxView(isChecked: true)
            CheckBoxView(isChecked: false)
        }
        .padding()
        .previewLayout(.sizeThatFits)
    }
}
5.Set up the cell of List

Create a file named ListItemCell.swift which contains the row item of List. It contains the CheckBox & title

import SwiftUI

struct ListItemCell: View {
    
    @ObservedObject var movie:MoviesModel
    var currentIndex:Int = 0
    var body: some View {
        HStack {
            Button(action: { self.movie.data[currentIndex].isFavorite.toggle() }) {
                CheckBoxView(isFilled: movie.data[currentIndex].isFavorite)
            }
            Text(movie.data[currentIndex].title)
            Spacer()
        }
    }
}

struct ListItemCell_Previews: PreviewProvider {
    static var previews: some View {
        ListItemCell(movie: MoviesModel())
            .padding()
            .previewLayout(.sizeThatFits)
    }
}
6. Create MoviesListView.swift which contains ListView

Use VStack where we about to place List & Button & use of StateObject so we can listen the @published values, Here we have used enumerated() on Array type because we required index of array

import SwiftUI

struct MoviesListView: View {
    @StateObject var movies = MoviesModel()
    var body: some View {
        VStack {
            List {
                ForEach(Array(movies.data.enumerated()), id: \.offset) { index, element in
                    ListItemCell(movie: movies, currentIndex: index)
                }
            }
            Button {
                print("Selected values ----->", movies.data.filter{$0.isFavorite})
            } label: {
                Text("Get Selected Values")
            }
        }
        .navigationBarTitle("All Movies")
    }
}

struct MoviesView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            MoviesListView()
        }
    }
}
// Note: Pass data as --@State var movies: [MovieEntity] = MockDataJSON.movies

Final code is here

Leave a Comment

Your email address will not be published. Required fields are marked *