Reputation: 470
I am coding without storyboard and I'm having this issue now that I can't find a good solution.
So I'm trying to call UIAlert
from UICollectionViewCell
like below.
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
This is what I found in stackoverflow and it works.
But when the ViewController
which has the UICollectionViewCell
is presented from the other ViewController
by present(_:animated:completion:)
like below, UIAlert
doesn't get called.
self.present(HomeController(), animated: true, completion: nil)
Does anyone know the solution for this issue?
Upvotes: 0
Views: 299
Reputation: 452
The fact that your cell is responsible for presenting an alert controller is not a good design, The cell
should delegate this. Having said that, it is possible to get the view controller where the cell
is in and present the alert controller using it:
extension UIView {
var parentController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
And in the place where you'd like to present the controller from the cell:
if let vc = cell.parentController {
vc.present(// alert controller)
}
Upvotes: 1
Reputation: 742
You can only present from the top most view controller. I assume you are trying to present alert controller from rootViewController
. That will not work if another viewController
has been presented over it already. Which in your case is HomeController
.
Present it over the HomeController
using self.present()
call. Not over the rootViewController
Upvotes: 0
Reputation: 3718
No, that will not work you need to implement delegate for that if you want to show alert on tapping action from cell
protocol CollectionViewCellDelegate: class {
func showAlert(_ cell: CollectionViewCell, _ message: String)
}
class CollectionViewCell: UICollectionViewCell {
...
....
.....
weak var delegate: CollectionViewCellDelegate?
@IBAction func yourButtonAction(_ sender: UIButton) {
self.delegate?.showAlert(self, "your message")
}
}
in your viewController
the collection's cellforRow
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectioView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
....
cell.delegate = self
return cell
}
conform to delegate like
extension YourClass: CollectionViewCellDelegate {
func showAlert(_ cell: CollectionViewCell, _ message: String) {
let alert = UIAlertController(title: "Alert Title", message: "Alert Message", style = .alert)
alert.addAction(UIAlertAction(title: "title", style: .default, handler: nil)
self.presentViewController(alert, animated: true, completion: nil)
}
}
Upvotes: 2