title: Properly delegate button action from custom Cell to delete rows in UITableView
body: <p>Still very much a Swift noob, I have been looking around for a proper way/best practice to manage row deletions in my <code>UITableView</code> (which uses custom <code>UserCell</code>s) based on tapping a <code>UIButton</code> inside the <code>UserCell</code> using delegation which seems to be the cleanest way to do it.</p>
  
  <p>I followed this example: <a href="https://stackoverflow.com/questions/39947076/uitableviewcell-buttons-with-action">UITableViewCell Buttons with action</a></p>
  
  <p><strong>What I have</strong></p>
  
  <p>UserCell class</p>
  
  <pre><code>protocol UserCellDelegate {
  
      func didPressButton(_ tag: Int)
  }
  
  class UserCell: UITableViewCell {
  
      var delegate: UserCellDelegate?
      let addButton: UIButton = {
  
          let button = UIButton(type: .system)
  
          button.setTitle("Add +", for: .normal)
          button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
          button.translatesAutoresizingMaskIntoConstraints = false
          return button
      }()
  
      override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
          super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
  
          addSubview(addButton)
          addButton.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -6).isActive = true
          addButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
          addButton.heightAnchor.constraint(equalToConstant: self.frame.height / 2).isActive = true
          addButton.widthAnchor.constraint(equalToConstant: self.frame.width / 6).isActive = true
      }
  
      func buttonPressed(_ sender: UIButton) {
  
          delegate?.didPressButton(sender.tag)
      }
  }
  </code></pre>
  
  <p>TableViewController class:</p>
  
  <pre><code>class AddFriendsScreenController: UITableViewController, UserCellDelegate {
  
      let cellId = "cellId"
      var users = [User]()
  
      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          return users.count
      }
  
      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  
          let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
  
          cell.delegate = self
          cell.tag = indexPath.row
  
          return cell
      }
  
      func didPressButton(_ tag: Int) {
  
          let indexPath = IndexPath(row: tag, section: 0)
  
          users.remove(at: tag)
          tableView.deleteRows(at: [indexPath], with: .fade)
      }
  }
  </code></pre>
  
  <p>where the <code>User</code>s in <code>users</code> are appended with a call to the database in the view controller.</p>
  
  <p><strong>My issues</strong></p>
  
  <ul>
  <li>The button in each row of the Table View is clickable but does not do anything</li>
  <li>The button seems to be clickable only when doing a "long press", i.e. finger stays on it for a ~0.5s time</li>
  <li>Will this method guarantee that the <code>indexPath</code> is updated and will not fall out of scope ? I.e. if a row is deleted at index 0, will deleting the "new" row at index 0 work correctly or will this delete the row at index 1 ?</li>
  </ul>
  
  <p><strong>What I want</strong></p>
  
  <p>Being able to click the button in each row of the table, which would remove it from the tableview.</p>
  
  <p>I must be getting something rather basic wrong and would really appreciate if a Swift knight could enlighten me.</p>
  
  <p>Many thanks in advance.</p>