Haasith Sanka
Haasith Sanka

Reputation: 15

How do I open a alertcontroller from a button in tableview cell in ios 9?

I want to open an Alertview with Call button and cancel button from button in a tableview cell.

var arrayOfUsernames: [PFObject] = [ ]

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return arrayOfUsers.count
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int{
    return 1
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Tutors"
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell: CustomTableViewCell = TutorTable.dequeueReusableCellWithIdentifier("Tutor") as! CustomTableViewCell

    cell.CUsername.text = self.arrayOfUsers[indexPath.row]
    cell.Classes.text = self.arrayOfClasses[indexPath.row]
    return cell

}

here is the customtableviewcell

import UIKit

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var CUsername: UILabel!
    @IBOutlet weak var Distance: UILabel!
    @IBOutlet weak var Classes: UILabel!
    @IBOutlet weak var Rating: UIImageView!

    @IBAction func bookNow(sender: AnyObject) {
    }

    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
    }

}

Upvotes: 0

Views: 831

Answers (2)

gigo
gigo

Reputation: 162

The way @meteochu suggested will work, however I prefer the protocol-delegate pattern.

Having in mind that the button is in a tableView cell, you can use a delegate so that your ViewController does the presenting of the Alert. Here is the protocol in your CustomtableViewCell:

protocol CustomTableViewCellDelegate: class {
   func customTableViewCell(customTableViewCell: cell, didTapButton button: UIButton)
}

Then add a property weak var delegate: CustomTableViewCellDelegate? in your CustomTableViewCell.

After that, again in your CustomTableViewCell, in your bookNow action, you fire the delegate like this:

self.delegate.customTableViewCell(self, didTapButton: sender as! UIButton) // Or just 'sender', if you set your action type to UIButton

Lastly, in your ViewController, where your tableView is, make sure you subscribe to the delegate of your CustomTableViewCell by implementing its protocol:

// Note the CustomTableViewCellDelegate here
class ViewController: CustomTableViewCellDelegate, UITableViewDelegate, UITableViewDataSource {
   // ...
   func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      let cell: CustomTableViewCell = TutorTable.dequeueReusableCellWithIdentifier("Tutor") as! CustomTableViewCell
      // ...
      cell.delegate = self
      return cell
   }

   // Implementing the protocol function
   func customTableViewCell(customTableViewCell: cell, didTapButton button: UIButton) {

      let phone = "+888888888888" // Sample phone number

      // Alert code
      let alertController = UIAlertController(title: "Call \(phone)", message:
        "Are you sure you want to perform this call?", preferredStyle: .Alert)

      // Call Button
      alertController.addAction(UIAlertAction(title: "Call", style: .Destructive) { action in
      // Code for making a call
      if let url = NSURL(string: "tel://\(phone)") {
          UIApplication.sharedApplication().openURL(url)
      } else
      })

      alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))  // Cancel button
      self.presentViewController(alertController, animated: true, completion: nil)  // Show the alert on the screen, here the ViewController does the presenting
   }
}

As you can see, in order to create an alert you need to use UIAlertController, calling it with a style of UIAlertControllerStyle.Alert a proper title and message.

Then you just add actions (buttons) with .addAction and type the code you want executed in their completion handlers. Lastly, you need to remember to present your alert with presentViewController.

If your number changes, the protocol has a reference to the cell that you can use to pass vie cell properties.

See more on the official documentation of UIAlertViewController class.

Upvotes: 1

andyl
andyl

Reputation: 83

Since UITableViewCell is a UIView subclass, and not UIViewController, you'll need to create a variable that holds a viewController you can present from.

First, you want to add a weak viewController var to your CustomTableViewCell. I recommend using a navigationController simply because you can use that to pushViewController: if you need it for other things, and you can control the stack from it if you need. If not, you can just use the UITableViewController.

In your cellForRowAtIndexPath: method, simply set the navigationController variable in your cell class to the current navigationController or the tableViewController:

cell.navigationController = self.navigationController or... cell.viewController = self

Once you do that, in your bookNow: method, you can now use a UIViewController to present the view. Here's what the code looks like...

Your UITableViewController class:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) → UITableViewCell? {
  let cell = tableView.dequeueReusableCellWithIdentifier("Tutor") as! CustomTableViewCell
  // setup your cell here
  cell.navigationController = self.navigationController
  // cell.viewController = self
  return cell
}

In your CustomCellClass:

weak var navigationController: UINavigationController?
// weak var viewController: UIViewController?

@IBAction func bookNow(sender: AnyObject) {
  let alertController = UIAlertController(/* setup */)
  // setup alertController
  self.navigationController?.presentViewController(alertController, animated: false, completion: nil)
  // self.viewController?.presentViewController(alertController, animated: false, completion: nil)
}

On a side note, I strongly advice changing your variable names to lower cases. Upper cases are usually used for Class names

Upvotes: 1

Related Questions