Zizoo
Zizoo

Reputation: 1764

How to manipulate UITableViewCell after another cell is tapped ? - Swift

How to manipulate UITableViewCell after another cell is tapped ?

I have 3 cells each one has UIPickerView the first cell's userInteractionEnabled is true but the 2nd and 3rd is false .. when the user tap the 1st cell the rest of cells's userInteractionEnabled should be true

I know I need to use userInteractionEnabled but how ? should I hold the cells in variables then manipulate when I need to?

Upvotes: 3

Views: 1491

Answers (3)

Luca Davanzo
Luca Davanzo

Reputation: 21528

I've read solutions above and are all valid of course, but I prefer a solution like this: I suppose you have an array of object to display (ignoring pattern you're using).

class MyObject: NSObject {
   var selected: Bool = false
}

class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var objects: [MyObject] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // init your objects: 
        // 1stObj.enabled = true
        // 2ndObj.enabled = false
        // 3rdObj.enabled = false
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
         let obj = self.objects[indexPath.row]
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
         cell.userInteractionEnabled = obj.enabled
         return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        for obj in self.objects {
           obj.selected = !obj.selected
        } 
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        tableView.reloadData()
    }
}

I think this solution is more scalable and maintainable, but is my opionion.

update

For manipulate cell outside of 'cellForRowAtIndexPath' function, you can do in this way for instance:

func manuallyModifyCell(atIndex index: Int, backgroundColor: UIColor = .clearColor()) {
    let indexPath = NSIndexPath(forRow: index, inSection: 0)
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        cell.backgroundColor = backgroundColor
    }
}

Upvotes: 3

donnywals
donnywals

Reputation: 7591

You could create a variable that holds on to the selection status of the first item:

var didSelectFirst = false

Then, in tableView(_:didSelectRowAtIndexPath:) you can tell the tableview to reload entirely, or just reload the two rows you want to reload.

if indexPath.row == 0 {
    didSelectFirst = true
    // reload all
    tableView.reloadData()
    // reload some
    tableView.reloadRowsAtIndexPaths([
        NSIndexPath(forRow: 1, inSection: 0),
        NSIndexPath(forRow: 2, inSection: 0)], withRowAnimation: .Automatic)
}

And in tableView(cellForRowAtIndexPath:) you can use the didSelectFirst variable to change userInteractionEnabled

if indexPath.row == 1 || indexPath.row == 2 {
    cell.userInteractionEnabled = didSelectFirst
}

Upvotes: 0

Willjay
Willjay

Reputation: 6469

Use a variable to keep track of userInteractionEnabled

var selectable: Bool = false

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = sections[indexPath.row]
    if selectable {
        cell.isUserInteractionEnabled = true
    } else {
        if indexPath.row != 0 { // Only first cell is enabled
            cell.isUserInteractionEnabled = false
        }
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print(indexPath.row)
    if indexPath.row == 0 {
        selectable = true
        tableView.reloadData()
    }
}

Upvotes: 0

Related Questions