Search code examples
iosswiftuitableviewsubclassuiactionsheet

Call UIActionSheet from UITableViewCell subclass


i am making a form, in which a have en bunch of different UITableViewCells, with different functions, so instead of clutter my UITableView class with ode for every action, i wanted to implement each function onto the cells subclass itself.

So, i have a cell right now, where a UIActionSheet pops up, but when i tap nothing happens, even though the delegate have been set.

Is my idea wrong and will an other way be better to do it? Here is some simple code.

import UIKit
class STypeCell: UITableViewCell, UIActionSheetDelegate {

    func chooseType() {
        var sheet: UIActionSheet = UIActionSheet()
        let title: String = "Please choose a course"
        sheet.delegate = self
        sheet.title  = title
        sheet.addButtonWithTitle("Cancel")
        sheet.addButtonWithTitle("A course")
        sheet.addButtonWithTitle("B course")
        sheet.addButtonWithTitle("C course")
        sheet.cancelButtonIndex = 0
        sheet.showInView(self.superview)
    }

    func actionSheet(sheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
        println("this never gets called")
    }

    func actionSheet(actionSheet: UIActionSheet, willDismissWithButtonIndex buttonIndex: Int) {
        println("this never gets called")
    }

    func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) {
        println("this never gets called")
    }

Solution

  • A TableViewCell should not have that kind of logic in it in an MVC Patterned framework as iOS is one.

    If you want to reuse that logic, than you should create a TableViewController (or ViewController) which you subclass instead. In the TableView Delegate methods you would then call your actions.

    Example:

    class MySuperTableView: UITableViewController, UIActionSheetDelegate {
    
    // [...]
    
      override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
      {
          self.chooseType()
      }
    
      func chooseType() {
          var sheet: UIActionSheet = UIActionSheet()
          let title: String = "Please choose a course"
          sheet.delegate = self
          sheet.title  = title
          sheet.addButtonWithTitle("Cancel")
          sheet.addButtonWithTitle("A course")
          sheet.addButtonWithTitle("B course")
          sheet.addButtonWithTitle("C course")
          sheet.cancelButtonIndex = 0
          sheet.showInView(self.view)
      }
    
      func actionSheet(sheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
          println("this never gets called")
      }
    
      func actionSheet(actionSheet: UIActionSheet, willDismissWithButtonIndex buttonIndex: Int) {
          println("this never gets called")
      }
    
      func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) {
          println("this never gets called")
      }
    
    // [...]
    }
    
    class MyChildTableView: MySuperTableView {
    
    // [...]
    
      override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
      {
          super.tableView(tableView, didSelectRowAtIndexPath: indexPath)
      }
    
    // [...]
    
    }
    
    class MyOtherChildTableView: MySuperTableView {
    
    // [...]
    
      override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
      {
          super.tableView(tableView, didSelectRowAtIndexPath: indexPath)
      }
    
    // [...]
    
    }
    

    Of course more logic would help like: What kind of row was tapped? Do I have other TableViewCells which can be tapped to and I therefore should check against?