One way could be to add a callback closure to a custom cell and execute it upon cell selection. your view controller would hook this callback up in tableView(_,cellForIndexPath:)
or tableView(_, cellWillAppear:)
import UIKit
class SelectionCallbackTableViewCell: UITableViewCell {
var selectionCallback: (() -> Void)?
@IBOutlet weak var button: UIButton!
@IBAction func buttonTapped(sender: UIButton) {
self.selectionCallback?()
}
override func layoutSubviews() {
super.layoutSubviews()
self.contentView.addSubview(self.button)
}
}
register the cell for the tableview. I did it in the storyboard.
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
var array = [1,1]
override func viewDidLoad() {
super.viewDidLoad()
for x in stride(from: 2, through: 30, by: 1){
let i = array[x-2]
let j = array[x-1]
array.append(i+j)
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SelectionCallbackTableViewCell
cell.selectionCallback = {
println("\(self.array[indexPath.row]) at \(indexPath.row) on \(tableView) selected")
}
cell.textLabel?.text = "\(self.array[indexPath.row])"
return cell
}
}
Now implement the callback closure as needed
cell.selectionCallback = {
println("\(self.array[indexPath.row]) at \(indexPath.row) on \(tableView) selected")
}
will result in logs like
832040 at 29 on <UITableView: 0x7fe290844200; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7fe2907878e0>; layer = <CALayer: 0x7fe290711e60>; contentOffset: {0, 697}; contentSize: {375, 1364}> selected
all possible helpful information are present:
- indexPath
- datasource object
- table view
- cell
if you want delete the cell after successfully informing your server, for a simple solution do:
cell.selectionCallback = {
println("\(self.array[indexPath.row]) at \(indexPath.row) on \(tableView) selected")
self.apiManager.deleteObject(obj, success: { response in
self.array.removeAtIndex(indexPath.row)
tableView.reloadData()
}, failure:{ error in
// handle error
})
}
Disclaimer:
Personally I don't recommend to implement datasources as UIViewController. It violates the SOLID principles.
Instead datasources should reside in their own classes.
For my own Projects I use an architecture I call "OFAPopulator", that allows me to create independent datasources for each section of a table or collection view.
I chose to implement it inside the view controller here for brevity.
I missed the button part. edited.
Example code: https://github.com/vikingosegundo/CellSelectionCallback