How to adjust the list of options that are visible based on previous choices via checkbox?

Hi everyone !

I'm a beginner in Swift and Xcode and I'm developing a little application for fun, which show you certain informations based on choices that you made via checkbox.

However, I don't know how to ajdust the list of options, because he ticked or not certain checkbox, that the user can see on the screen.

If you could help me or put me on the track it would be very kind !


Thank you for help and excuse my english, I'm french.

Have a nice day

Where are those options listed ?

Is it a tableView ?

Whatever it is, you will test the user choice with:


item1.isHidden = checkBox1.state == NSControl.StateValue.off

Yes, the options are listed in a tableView because I wanna put a searchBar so, yes I'm using a tableView

Okay thank you for your time !

You have 2 solutions at least:


- hide the row by setting its height to zero :


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    var rowHeight:CGFloat = 0.0

    if checkBox1.state == NSControl.StateValue.off {     // of course, you need to use the checkbox that is relevant for this row
        rowHeight = 0.0
    }else{
        rowHeight = 30.0    //or whatever you like
    }

    return rowHeight
}


Or remove the row from the datasource of the table and reload tableView.


If you need more help, please post your code where you define:

- the checkboxes

- the datasource for the tableView

- which row to hide depending on checkbox status

Finally, I'm not able to use a tableView I thing, because I watched some tutorials on Youtube et it seems to me quite difficult

So, here's my code where i define the checkbox :

// Checkbox

@IBAction func checkBoxTapped(_ sender: UIButton) {

if sender.isSelected {

sender.isSelected = false

} else {

sender.isSelected = true }

}

Then I use a button and I put an image of an unchecked et checked box.

I'm certainly not in the good track no? Is it possible to do what I want with this code (which I'll multiply according to the number of checkboxes in my app)

What you show is how to draw the chackbox, not how to control the content to display.


You have to explain:


- How many checkboxes have you ? Only one ? Several ?

I understand only one.

- Where do you store information ? In an array of Strings ?

That could be

     let informations : [String] = // enter the strings

- How do you define which information should be displayed ?

Could be an array of Bool of the same size as informations

     var infosToDisplay : [Bool] = []


In viewDidLoad, you should initialize with

     infosToDisplay = Array(repeating: true, count: informations.counts)



In IBAction, you should then set the infosToDisplay

    @IBAction func checkBoxTapped(_ sender: UIButton) {
        if sender.isSelected {
            sender.isSelected = false
           // turn some infosToDisplay to true or false
          infosToDisplay[0] = false     // just to illustrate
        } else {
            sender.isSelected = true
           // turn some infosToDisplay to false or true
          infosToDisplay[0] = true     // just to illustrate
        }
    }



Then, use the tableView:


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    var rowHeight:CGFloat = 0.0

    if infosToDisplay[indexPath.row] { 
        rowHeight = 30.0
    } else {
        rowHeight = 0.0    //or whatever you like
    }

    return rowHeight
}

For the moment I onyl have one checkbox but there wiil be several for sure in the future

I store information in an Array of strings like you said and I want all the strings of the array to be displayed on the screen with checkboxes in front of each propositions. Next, I want to display certain informations according to if this checkbox is ticked, or this other one, or those 3 etc...

About what you asked me "How do you define which information should be displayed ?", I didn't defined anything yet but I think I'll use the array of Bool that you said


For the moment, I'm here

@IBOutlet weak var tblView: UITableView!


let fruitsNamesArray = ["Abricot", "Ananas", "Avocat", "Brugnon", "Cacahuète", "Cassis", "Cerise", "Châtaigne", "Citron", "Citron Vert", "Clémentine", "Coing", "Datte", "Figue", "Fraise", "Framboise", "Fruit de la passion", "Grenande", "Groseille", "Kiwi", "Litchi", "Mandarine", "Mangue", "Marron", "Melon", "Mirabelle", "Mûre", "Myrtille", "Nectarine", "Noisette", "Noix"]


// Checkbox

@IBAction func checkBoxTapped(_ sender: UIButton) {

if sender.isSelected {

sender.isSelected = false

} else {

sender.isSelected = true }

}


@IBAction func checkBoxTapped2(_ sender: UIButton) {

if sender.isSelected {

sender.isSelected = false

} else {

sender.isSelected = true }

}


And for example, i would like that my app show me some recipes according to what I have ticked

Some points still not clear.


- So you have the checkbox (one now, several tomorrow) to control what needs to be displayed. I call them Type 1

So, what are the 2 IBActions ? Referring to which buttons ?


- You say you have checkboxes in front of each propositions

What do you control with those checkboxes ? (I call them type 2)

Are they already used ?


Anyway, I would change your code, to prepare for the future

- create an IBOutlet collection to all the checkbox of Type 1

    @IBOutlet var checkBoxes: [UIButton]!

- connect to the appropriate checkboxes

- define a tag from 0 to N-1 for the checkboxes N = number of checkboxes


Use the same IBAction for all checkboxes

If you need to know which checkbox, test the tag



@IBOutlet var checkBoxes: [UIButton]!
@IBOutlet weak var tblView: UITableView!

    let fruitsNamesArray = ["Abricot", "Ananas", "Avocat", "Brugnon", "Cacahuète", "Cassis", "Cerise", "Châtaigne", "Citron", "Citron Vert", "Clémentine", "Coing", "Datte", "Figue", "Fraise", "Framboise", "Fruit de la passion", "Grenande", "Groseille", "Kiwi", "Litchi", "Mandarine", "Mangue", "Marron", "Melon", "Mirabelle", "Mûre", "Myrtille", "Nectarine", "Noisette", "Noix"]
     let recipes = ["Tarte Tatin", "Tarte aux pommes", "Biscuit roulé"]

    // Checkbox
    @IBAction func checkBoxTapped(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        switch sender.tag {
          case 0 : // depending on checvkBoxes[0] selected, show or hide some information (index) by setting infosToDisplay[index]
               infosToDisplay[0] = true     // just to illustrate      : show "Tarte Tatin"
               infosToDisplay[0] = false     // just to illustrate      : hide "Tarte aux pommes"
               infosToDisplay[0] = true     // just to illustrate      : show "Biscuit roulé"
          default: break
        }
    }

But, you do not explain

- how is information defined

I assume you have an Array

recipes = ["Tarte Tatin", "Tarte aux pommes", "Biscuit roulé"]

- how you select to show/hide some information depending on check

SO, PLEASE, show the complete code of the class

It is likely that you should define some data structures, as dictionaries, such as

var ingredients : [String: [String]]
ingredients["Tarte Tatin"] = ["Pomme"]     // Celui là manque …
ingredients["Biscuit Roulé"] = ["Marron", "Groseille"] 

Final note: in IOS App, usually you use switch instead of checkboxes. But it is up to you.

Okay, I'll try to explain clearly what I've in my mind :

1st : the @IBActions are 2 checkboxes that I've experienced to see if it run

2nd : you probably didn't understand well what I was trying to do :

The user have a list of ingredients like fruits for example, with checkboxes in front of each ingredient, so the user can tick whatever he has with him and the app will show him which recipe he could cook based on what he has at his home

So for example, the user has some bananas, apples, cake batter --> so the app will show him some recipe of cake which contain apple and bananas

We don't need type 1, type 2 because every checkboxes are the same type

That's why I didn't answer to your question about how are informations defined because I don't know what to do and how to do it to realize my idea

So, what should I do about this, what would you advise me about data structures? dictionnaries? something else?


However, thank you for that :

- create an IBOutlet collection to all the checkbox of Type 1

  • @IBOutlet var checkBoxes: [UIButton]!
  • - connect to the appropriate checkboxes

    - define a tag from 0 to N-1 for the checkboxes N = number of checkboxes


    I didn't know we could do this so it seems easier and more convenient than my way

    And thank you very much for the big piece of code that you gave me because it puts me on the track of what I'm looking for here


    I didn't understand (again, I'm sorry..) your final note

    OK.


    You can display directly the list of ingredients checkboxes, each holding the name of an ingredient ("Pomme", …


    Define

    struct Recipe {
         var name: String
         var ingredients: [String]
         var isPossible : Bool
    }
    
    let tarteAuxPommes = Recipe(name: "Tarte aux pommes", ingredients: ["Pomme"])
    let biscuitRoule = Recipe(name: "Biscuit roulé", ingredients: ["Marron", "Chocolat"])
    var recipes : [Recipe] = [tarteAuxPommes, biscuitRoule]


    Create a UILabel to hold the result (define it in IB as 0 line and make it high enough to hold a long list

    @IBOutlet var possibleRecipesList: UILabel!


    The IBAction should become


        @IBAction func checkBoxTapped(_ sender: UIButton) {
            sender.isSelected = !sender.isSelected
    
            var selectedIngredients : [String] = []
    
             // Scan all the checkboxes to find which ingredients are ticked
            for checkBox in checkBoxes {
                   if checkBox.isSelected { selectedIngredients.append(checkBox.title) }
            }
    
              // Look at all recipes to see if its ingredients are available, then it will be selected
            for recipe in recipes {
               recipe.isPossible = selectedIngredients.contains(recipe.ingredients)         // All ingredients of the recipe are ticked
             }
    
              // Display the list of recipes that are possible. For instance in a TextView ; to make it simple, here in a label
               var possibleRecipes = ""
              for recipe in recipes where recipe.isPossible {
                    possibleRecipes = possibleRecipes + recipe.name + "\n"   // All ingredients of the recipe are ticked
              }
              possibleRecipesList.text = possibleRecipes
        }

    but that may not be the best option.


    You'd better hold the list of ingredients in a tableView. Otherwise, if you have 100 of them, that will be pretty hard to manage.


    - Define custom cell (subclass of UITableViewCell, and create its xib at the same time.

    - In xib, you put a checkbox which title will hold the ingredient name

    For the moment, there is not so much ingredient so I could use a tableView, but if the app is good and if it evolves, I will find another way


    Perfect, thank you very much, could you give me a way to contact you if I have another question or problem with the app? If it doesn't bother you of course, I'll understand !

    Have a nice day Claude :-)

    Did you completely solve your problem ? If so, please don't forget to close the thread. Have a nice day.

    Hi,

    I came across your post and it sounds interesting. Maybe you have already solved it. But here is what I would try:

    NSMutableArray *ingredientsArray = Have the checkboxes update an array every time a checkbox is checked or unchecked. It if it checked, it adds its ingredient to the array. If it is unchecked, it removes its ingredient from the array.


    NSArray *recipeArray = every recipe has its ingredients stored in its own array.


    Once all the check boxes are chosen, then a button to "get result" or it could be done as checkboxes are selected/deselected--do a search/sort/compare/etc. with the arrays to find a match for ingredients to recipes. This also opens up possibilities such as, if you had x ingredient, you could make x.

    How to adjust the list of options that are visible based on previous choices via checkbox?
     
     
    Q