-1

While attempting to anchor an alert's popoverPresentationController to a specific UICollectionViewCell, I discovered it would only anchor to the UINavigationController.

What steps do I need to take in order to programmatically trigger this alert controller and anchor it to the user-selected cell?

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let selectedCell = collectionView.dequeueReusableCell(withReuseIdentifier: PersonCell.reuseIdentifier, for: indexPath)
    let person = people[indexPath.item]

    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { ... }))
    alert.addAction(UIAlertAction(title: "Rename", style: .default, handler: { ... }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))

    alert.modalPresentationStyle = .popover
    alert.popoverPresentationController?.sourceView = selectedCell
    alert.popoverPresentationController?.sourceRect = CGRect(x: selectedCell.bounds.maxX, y: selectedCell.bounds.midY, width: 0, height: 0)
    present(alert, animated: true)
}
  • Add the code that you've used to show the alert controller. – PGDev Dec 31 '19 at 05:57
  • Have you tried [https://stackoverflow.com/questions/24224916/presenting-a-uialertcontroller-properly-on-an-ipad-using-ios-8](https://stackoverflow.com/questions/24224916/presenting-a-uialertcontroller-properly-on-an-ipad-using-ios-8) – Cerlin Dec 31 '19 at 06:08
  • @PGDev added the code that I'm currently using, which seems to align with the documentation – turbomattik Dec 31 '19 at 06:20
  • @Cerlin Yes, but thanks for the link; I had not seen that thread yet but it basically says the same things I've tried. I also tried safely unwrapping the property and setting inside. – turbomattik Dec 31 '19 at 06:21
  • as mentioned in the link i provided, `alert.popoverPresentationController` will be nil if the modal presentation style is not `popover`. Before accessing `popoverPresentationController`, execute `alert.modalPresentationStyle = .popover` – Cerlin Dec 31 '19 at 06:33
  • @Cerlin Tried placing it immediately after `alert` declaration and line before accessing `popoverPresentationController`. Neither seemed to work, the alert continues to display anchored to `leftBarButtonItem`. – turbomattik Dec 31 '19 at 06:43

1 Answers1

3

The problem with your code is that you are dequeuing a re-useable cell instead of getting the cell at position.dequeueReusableCell will create a new cell if it doesn't have a cached copy ready. In your case this is creating a cell with size zero and frame zero (x = 0, y = 0) so the pointer is pointing to that.

You should use collectionView.cellForItem(at: indexPath) instead

So your final code will look something similar to below code

if let selectedCell = collectionView.cellForItem(at: indexPath) {
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { ... }))
    alert.addAction(UIAlertAction(title: "Rename", style: .default, handler: { ... }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))

    alert.modalPresentationStyle = .popover
    alert.popoverPresentationController?.sourceView = selectedCell
    alert.popoverPresentationController?.sourceRect = CGRect(x: selectedCell.bounds.midX, y: selectedCell.bounds.maxY, width: 0, height: 0)
    present(alert, animated: true)
}

Here is the output of my sample

enter image description here

Cerlin
  • 6,622
  • 1
  • 20
  • 28