1
votes

My table view custom cell row has 3 elements: A UITextField embedded in a UIScrollView, a label, and a button. 'didSelectRowAt indexPath' function ONLY runs when any 2 of the 3-row elements are simultaneously tapped. Why is this? I did not add any touch gestures.

potentially useful information: tableview delegate and dataSource are set to self. Removing tableView.reloadData() will result in changes from code not being reflected in the UI. self.tableView.beginUpdates() & self.tableView.endUpdates() have no effect.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("test")
    if dataSource.data[indexPath.row].isDataCollapsed() {
        print("expanded")
        dataSource.data[indexPath.row].isCollapsed = false
        tableView.reloadData()
    }
}

Thank you in advance!

EDIT:

I resorted to using touch gestures since I couldn’t figure it out. Thank you.

2
try running this code on main threadJarvis The Avenger
Disable touch events for UITextField and UIButton by giving 'isUserInteractionEnabled = false' to they it.AshokPolu
@JarvisTheAvenger how would I do that? @ AshokPolu, thanks you for the recommendation however that did not work. Any other suggestions?Mansur Ahmed
I think u should try out it first by disabling UI elements user interaction.Jarvis The Avenger
@MansurAhmed Having the same problem, did you figure it out?George

2 Answers

2
votes

Ok so I finally figured it out. It turns out that

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}

does not work in tandem with EXISTING custom tap gestures (unsure if it is only limited to tap gestures or gestures in general). This means that you CANNOT have a tap gesture active in the same View Controller (VC) at the same time as the tableView, else your didSelectRowAt function will not respond to touch properly.

There are two solutions to this I've come up with. One is a workaround: add a custom tap gesture as I did previously, and as shown (or similar to depending on your use case) by @George_E 's answer above to get your tableView to respond to DidSelectRowAt. OR you can work your other pre-existing custom tap gestures in the view around with your tableView activity. By this, I mean when your tableView is active and requires some tap gesture interaction, disable the custom tap gestures. Conversely, when the tableView is inactive or doesn't require tap gesture interactions, re-enable your custom tap gestures. Place the below code wherever you'd like to disable/enable your custom tap gestures:

for gesture in (self.view?.gestureRecognizers)! {
        if gesture.isKind(of: UITapGestureRecognizer.self) {
            gesture.isEnabled = false // or true if you want to enable it
        }
    }
0
votes

Outdated - See accepted answer


Original answer

I had the same problem, and couldn't fix it either. So I decided to go with adding a tap gesture, which also animates like before.

Within my didMoveToSuperview of the table:

// Set delegates
delegate = self
dataSource = self

// Setup cells
register(MyCustomTableCell.self, forCellReuseIdentifier: "cellId")
allowsSelection = false // <-- Stops the user from tapping with 2
                        //     fingers, creating a permanent selection.

The function in the table view where the cell is setup (remember to initalize with the custom class down below):

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Create cell
      let cell = MyCustomTableCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: "cellId")
     /* OR */
      let cell = dequeueReusableCell(withIdentifier: "cellId")
    
    // Setup cell
    /* ... */

The custom class to use for the table cell to get what we want:

final class MyCustomTableCell: UITableViewCell {
    
    override func didMoveToSuperview() {
        // Create the tap gesture
        let gesture = UITapGestureRecognizer(target: self, action: #selector(tapGesture(gesture:)))
        addGestureRecognizer(gesture)
    }
    
    @objc private func tapGesture(gesture: UITapGestureRecognizer) {
        setSelected(true, animated: true)
        setSelected(false, animated: true)
        print("Tap!")
    }
}

Hope someone finds this useful! Workarounds are best to be avoided, but it was required in this situation. 😀