Titus
Titus

Reputation: 349

How to execute data inside TableViewCell as a button?

enter image description hereI am creating an app where in the menus are listed inside TableViewCell. The menus are already inside the cell but unfortunately, when I clicked one of the menus, It is not executing the action that the menu should do. For example, i tapped the logout label it does not executing showlogoutDialog. I already used breakpoints but it seems the data inside the table are just plain text. Image below is the sample output of the table. Hope you can give some solution regarding this issue. Thank you.

Screen Record

DoctorMenuTableCell.swift

class DoctorMenuTableCellTableViewCell: UITableViewCell {


@IBOutlet weak var titleLabel: UILabel!


override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

MoreOptionViewController.swift

private let menuIdentifier = "MenuCell"

class MoreOptionViewController: UIViewController {

@IBOutlet weak var doctorMenuTableView: UITableView!

}

override func viewDidLoad() {
    super.viewDidLoad()

self.doctorMenuTableView.dataSource = self
self.doctorMenuTableView.delegate = self

}

//MARK: Function

func showLogoutDialog() {
    //create alert
    let alert = UIAlertController(title: "Confirmation",  message: "Are you sure you want to logout?", preferredStyle: .alert)

    //add the actions (button)
    alert.addAction(UIAlertAction(title: "No", style: .default, handler: nil))
    alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (alert) in
        self.logout()
    }))
    self.present(alert, animated: true, completion: nil)

}

func logout() {
    NotificationCenter.default.post(name: Notification.Name(deleteUserDataNotificationName), object: nil)
   }

}


extension MoreOptionViewController: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {  
  case 0:
      return Menu.More.items.count
  default: return 0
 }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let row = indexPath.row

    switch indexPath.section {
    case 0:
        let cell = tableView.dequeueReusableCell(withIdentifier: menuIdentifier, for: indexPath) as! DoctorMenuTableCell

        cell.titleLabel.text = Menu.More.items[row].value

        if row == 1{
            cell.titleLabel.textColor = UIColor.red
            cell.accessoryType = .none   
        }

        return cell
    default:
        return UITableViewCell()
    }
}

func tableView(_tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    switch indexPath.section {
    case 0: break
    case 1:
        switch indexPath.row {
            case 0:
                let alertController = UIAlertController(title: "Info", message: "No available data", preferredStyle: .alert)
                alertController.addAction(UIAlertAction(title: "OK", style: .default))

                self.present(alertController, animated: true, completion: nil)
        case 1: showLogoutDialog()
        default: break
    }

    default: break

    }

}

Upvotes: 2

Views: 201

Answers (3)

Vijay Kahar
Vijay Kahar

Reputation: 1076

First Create Extension if UIViewController as Below,

Create a swift File Named Extension.swift or whatever you want,

extension UIViewController
{
    func showLogoutDialog() {
        //create alert
        let alert = UIAlertController(title: "Confirmation",  message: "Are you sure you want to logout?", preferredStyle: .alert)

        //add the actions (button)
        alert.addAction(UIAlertAction(title: "No", style: .default, handler: nil))
        alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (alert) in
            self.logout()
        }))
        self.present(alert, animated: true, completion: nil)

    }
    func logout() {
        print("helllllo")
        NotificationCenter.default.post(name: Notification.Name(deleteUserDataNotificationName), object: nil)
    }
}

Now call showLogoutDialog() on cellForRowAt,

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   switch indexPath.section {
    case 1: break
    case 0:
         switch indexPath.row {
           case 0:
              let alertController = UIAlertController(title: "Info", message: "your data", preferredStyle: .alert)
              alertController.addAction(UIAlertAction(title: "OK", style: .default))

              self.present(alertController, animated: true, completion: nil) 
            break
            case 1: showLogoutDialog()
            break
            default: break
         }
         break
         default: break

     }

Upvotes: 0

Amir Khan
Amir Khan

Reputation: 1318

Check your Did Select Method, your cells are under Section 0 and Did Select work for section 1.

Also check isUserInteractionEnabled for both TableView as well as Cell and add breakpoint on didSelectRowAt and check which switch case is working.

Code:

func numberOfSections(in tableView: UITableView) -> Int {
  return 2
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   switch section {  
     case 0:
         return Menu.More.items.count
     default: return 0
    }
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    switch indexPath.section {
      case 0:
          let cell = tableView.dequeueReusableCell(withIdentifier: menuIdentifier, for: indexPath) as! DoctorMenuTableCell
          cell.titleLabel.text = Menu.More.items[row].value

          if indexPath.row == 1{
              cell.titleLabel.textColor = UIColor.red
              cell.accessoryType = .none   
          }

         return cell
      default:
         return UITableViewCell()
      }
 }



func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   switch indexPath.section {
    case 1: break
    case 0:
         switch indexPath.row {
           case 0:
              let alertController = UIAlertController(title: "Info", message: "No available data", preferredStyle: .alert)
              alertController.addAction(UIAlertAction(title: "OK", style: .default))

              self.present(alertController, animated: true, completion: nil) 
            break
            case 1: showLogoutDialog()
            break
            default: break
         }
         break
         default: break

     }

  }

Upvotes: 1

Robert Dresler
Robert Dresler

Reputation: 11150

Look how many sections you have. You have just one, but inside didSelectRowAt you're showing alerts just if section index is 1 which in you case index never is.

You just need to check if row is 0 or 1

func tableView(_tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    switch indexPath.row {
    case 0: 
        let alertController = UIAlertController(title: "Info", message: "No available data", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default))
        present(alertController, animated: true)
    case 1:
        showLogoutDialog()
    default: 
        return
    }
}

So, if you have only one section, you can also update data source methods. Also you should handle cases that cell isn't in IndexPath with row index 1 since cells are dequeued

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return Menu.More.items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: menuIdentifier, for: indexPath) as! DoctorMenuTableCell

    let row = indexPath.row
    cell.titleLabel.text = Menu.More.items[row].value

    cell.titleLabel.textColor = .black 
    cell.accessoryType = .detailButton

    if row == 1
        cell.titleLabel.textColor = .red
        cell.accessoryType = .none
    }

    return cell
}

Upvotes: 0

Related Questions