0

I am attempting to change which cells are displayed based on the selection a user makes in a UIPickerView. Right now, I am using the method cell.hidden = true. However, the problem with this is that the cell hides but there is white blank space the size of the cells that are hidden. I want to make it so the cells are hidden/removed (with data saved) from the table view. Here is the current code.

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    var numRows = tableData.count
    if(timeTextfield.text == timeData[1]) {
        numRows = 25
    }
    else if(timeTextfield.text == timeData[2]) {
        numRows = 30
    }
    return numRows
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:TblCell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TblCell
    var lblOneBool = true
    var lblTwoBool = true
    var lblThreeBool = true
    var lblFourBool = true

    if(timeTextfield.text == timeData[2]) {
        cell.hidden = false
        cell.lblTime.text = tableData[indexPath.row + 25]
        cell.lblOne.text = lblOneData[indexPath.row + 25]
        cell.lblTwo.text = lblTwoData[indexPath.row + 25]
        cell.lblThree.text = lblThreeData[indexPath.row + 25]
        cell.lblFour.text = lblFourData[indexPath.row + 25]
    }
    else {
        cell.lblTime.text = tableData[indexPath.row]
        cell.lblOne.text = lblOneData[indexPath.row]
        cell.lblTwo.text = lblTwoData[indexPath.row]
        cell.lblThree.text = lblThreeData[indexPath.row]
        cell.lblFour.text = lblFourData[indexPath.row]
    }

    if(cell.lblOne.text != "Available") {
        lblOneBool = false
    }
    if(cell.lblTwo.text != "Available") {
        lblTwoBool = false
    }
    if(cell.lblThree.text != "Available") {
        lblThreeBool = false
    }
    if(cell.lblFour.text != "Available") {
        lblFourBool = false
    }

    if(playerTextfield.text == playersData[1]) {
        if(lblOneBool || lblTwoBool || lblThreeBool || lblFourBool) {
            cell.hidden = false
        }
        else {
            cell.hidden = true
        }
    }
    else if(playerTextfield.text == playersData[2]) {
        if((lblOneBool && lblTwoBool) || (lblOneBool && lblThreeBool) || (lblOneBool && lblFourBool) || (lblTwoBool && lblThreeBool) || (lblTwoBool && lblFourBool) || (lblThreeBool && lblFourBool)) {
            cell.hidden = false
        }
        else {
            cell.hidden = true
        }
    }
    else if(playerTextfield.text == playersData[3]) {
        if((lblOneBool && lblTwoBool && lblThreeBool) || (lblOneBool && lblTwoBool && lblFourBool) || (lblOneBool && lblThreeBool && lblFourBool) || (lblTwoBool && lblThreeBool && lblFourBool)) {
            cell.hidden = false
        }
        else {
            cell.hidden = true
        }
    }
    else if(playerTextfield.text == playersData[4]) {
        if(lblOneBool && lblTwoBool && lblThreeBool && lblFourBool) {
            cell.hidden = false
        }
        else {
            cell.hidden = true
        }
    }
    return cell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 120
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let row = indexPath.row
    performSegueWithIdentifier(conSegueIdentifier, sender: indexPath)
    print(tableData[row])
    if(timeTextfield.text == timeData[2]) {
        tblIndex = row + 25
    }
    else {
        tblIndex = row
    }
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
//end of tableview
Daniel Storm
  • 18,301
  • 9
  • 84
  • 152
SwaggyMcMuffins
  • 27
  • 1
  • 1
  • 9

2 Answers2

0

There are many different approaches you can do

A simple one is to implement heightForRowAtIndexPath of the UITableView delegate and return 0 for rows you don't want to show

Another approach would be to remove those rows from your tableData altogether. So maybe have a "filteredArray" and a nonfiltered array. That way you can always return back to your non filtered array when not filtering

MobileMon
  • 8,341
  • 5
  • 56
  • 75
  • Do I change the existing heightForRowAtIndexPath function or call the method inside the if statements? @MobileMon – SwaggyMcMuffins Dec 23 '15 at 19:49
  • @SwaggyMcMuffins You have to change existing heightForRowAtIndexPath function as follows func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { if(playerTextfield.text == playersData[3]) { if((lblOneBool && lblTwoBool && lblThreeBool) || (lblOneBool && lblTwoBool && lblFourBool) || (lblOneBool && lblThreeBool && lblFourBool) || (lblTwoBool && lblThreeBool && lblFourBool)) { return 120 } else { return 0 } } – Ajinkya Patil Dec 23 '15 at 20:07
  • @AjinkyaPatil When I do this, all of the cells change heights. How do I fix this? – SwaggyMcMuffins Dec 23 '15 at 20:45
  • @SwaggyMcMuffins you have to give conditions to check which rows you want to hide & & which rows you want to show.. so in your code you have added conditions to check you have to add the same conditions in your heightForRowAtIndexPath as follows: – Ajinkya Patil Dec 24 '15 at 06:01
  • if(playerTextfield.text == playersData[1]) { if(lblOneBool || lblTwoBool || lblThreeBool || lblFourBool) { return 120 } else { return 0 } } else if(playerTextfield.text == playersData[2]) { if((lblOneBool && lblTwoBool) || (lblOneBool && lblThreeBool) || (lblOneBool && lblFourBool) || (lblTwoBool && lblThreeBool) || (lblTwoBool && lblFourBool) || (lblThreeBool && lblFourBool)) { return 120 } else { return 0 } } – Ajinkya Patil Dec 24 '15 at 06:03
  • add remaining conditions in your heightForRowAtIndexPath like above – Ajinkya Patil Dec 24 '15 at 06:04
  • @AjinkyaPatil I added the remaining conditions. However my problem is now this: http://stackoverflow.com/questions/34444057/thread-1-exc-bad-access-code-2 – SwaggyMcMuffins Dec 30 '15 at 15:44
  • @SwaggyMcMuffins question is deleted. Is your problem solved? – Ajinkya Patil Dec 30 '15 at 18:24
0

Do not hide the cell, change your data.

But I have to say that your current cellForRowAtIndexPath is a mess and therefore I am currently unable to give you code that solves your exact situation. I can only give you general advice.

That advice is to not include too much logic into your cellForRowAtIndexPath. Hiding your cells sounds a like a very, very, veeery bad idea. When you want to hide a cell, remove its data from the backing data structure and reload the tableview. Whenever I deal with some kind of filterable table- or collectionview, I have one array that holds all the data that could be displayed. But what actually gets used everywhere is a filtered copy of it. That way is it easy to remove whatever filter you applied and you have the full flexibility of removing whatever cell you want to hide.

A couple of problems I see with your code:

  • tableData[indexPath.row + 25] - why +25?
  • 5 different data arrays! Use a class to hold the values that are stored for each data entry distributed across the 5 arrays
  • lblOneBool, lblTwoBool - what are those? Dont just enumerate your variables, if they are simply 4 bools which have similiar functionality, use an array instead or better naming.
  • as previously states: you have tooo much business logic in your cellForRowAtIndexPath
luk2302
  • 55,258
  • 23
  • 97
  • 137
  • the +25 has to do with another filter and then for the different arrays, I put them in a class. Then make an array of that class to filter through? (I'm new to swift) – SwaggyMcMuffins Dec 23 '15 at 17:35
  • @SwaggyMcMuffins I would definitely create a class to hold the values and then only use *one* array of instances of that class – luk2302 Dec 23 '15 at 17:36