0
votes

I am trying to call a UIAlertController from within my UITtableViewCell when my function is called. It gives me an error saying present is not available. I understand it's not within a ViewController. I am looking for an approach to access it.

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

    let tapGestureShareImageView = UITapGestureRecognizer(target: self, action: #selector(self.shareImageTouchUpInside))
    shareImageView.addGestureRecognizer(tapGestureShareImageView)
    shareImageView.isUserInteractionEnabled = true
}

@objc func shareImageTouchUpInside() {
    showAction()
}

func showAction() {
    let alertController = UIAlertController(title: "Action Sheet", message: "What do you like to do", preferredStyle: .alert)

    let okButton = UIAlertAction(title: "Done", style: .default, handler: { (action) -> Void in
        print("Ok button tapped")
    })

    let deleteButton = UIAlertAction(title: "Skip", style: .destructive, handler: { (action) -> Void in
        print("Delete button tapped")
    })

    alertController.addAction(okButton)
    alertController.addAction(deleteButton)

    present(alertController, animated: true, completion: nil)
}
3
Ideally, don't show a view controller from a cell. Instead, create a delegate or a callback function and pass the event to the view controller and present alert from there.Sulthan

3 Answers

3
votes

You can try to use delegate

protocol AlertShower{
    func showAlert(TableCustomCell)
}

class TableCustomCell: UITableViewCell {
    var delegate: AlertShower?

    @IBAction func showClicked(_ sender: UIButton) {
        self.delegate?.alertShower(sender:self)
    }
}

in the VC

class viewController: UIViewController, AlertShower {

    override func viewDidLoad() {
        super.viewDidLoad()

    }


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

         let cell = areaSettTable.dequeueReusableCell(withIdentifier:CellIdentifier1) as! TableCustomCell

         cell.delegate = self

         return cell
    }

    func showAlert(sender:TableCustomCell) {

      // show alert here

    }
}
1
votes

Present is only available to ViewControllers. You are going to have to redirect the touch event to your view controller. The most common way of doing this would be having a delegate property in your UITableViewCell.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276

-1
votes

I ran into a similar problem myself when creating a custom activity indicator from a subclassed UIView. What I did was create the 'show' function (in the subclass) and pass in a UIViewController parameter, like so:

public func play(inView view: UIViewController) {
//Perform action here
view.present(alertController, animated: true, completion: nil)
}

Simply call it in your view controller like so:

CustomClass.play(inView: self)

Hopefully this helps!