Description: an experiment on how to separate the viewController from tableViewDataSource while at the same time reduce the tableView interaction code. Source Code


I started out with the wish to write a rounded UIView extension, which was quite easy to achieve. Somehow along the way I decided to revisit the previous Dribble code and make some improvement:

– a separate TableView DataSource handles the data manipulation and give feedback to the main ViewController when the user interaction is performed. The ViewController can then perform the corresponding view updates or other actions. In fact, almost all actions that triggered by user interaction can use the same function to call back the main ViewController:

func tableViewCellActionHandler(item: AnyObject, indexPath: NSIndexPath, action: TableViewActionType) {
        switch action {
        case .Edit:
        case .Favoriate:
            favShots.append(item as! Shot)
            tableView.setEditing(false, animated: true)
        case .Save:
            if let cell = tableView.cellForRowAtIndexPath(indexPath) as? ShotTableViewCell {
                if let image = cell.shotImageView?.image {
                    tableView.setEditing(false, animated: true) // imp
        case .DidSelect:
            println("selecting \(indexPath.row)")
        case .DidDeselect:
           tableView.deselectRowAtIndexPath(indexPath, animated: true) // call it to make sure it does deselect. (Sometime, it doesn't)
           println("deselected \(indexPath.row)")

        case .Delete:
        case .More:

The TableView Action types are custom defined:

public enum TableViewActionType: String {
    case Edit  = "Edit"
    case Save = "Save"
    case More = "More"
    case Favoriate = "Favoriate"
    case Delete = "Delete"
    case DidSelect = "DidSelect"
    case DidDeselect = "DidDeselect"


The rounded UIView extension which can be called easily with:  userImageView.round()

public extension UIView {
        public func round() {
        let width = bounds.width < bounds.height ? bounds.width : bounds.height
        let mask = CAShapeLayer()
        mask.path = UIBezierPath(ovalInRect: bounds.rectByCentering(width, height: width)).CGPath
        self.layer.mask = mask