共有を完了したときに起こる不具合
テキストやファイルなどを共有するときに使用するUIActivityViewControllerですが、iOS13の環境では共有が終了したタイミングでUIActivityViewControllerを表示した親のUIViewControllerまでdismissしてしまう不具合があるようです。
参考: iOS 13 UIActivityViewController automatically present previous VC after image saving
発生条件は曖昧?
上記のstack overflowの記事では特に言及がないようですが、僕が遭遇した不具合の発生条件は以下でした。
発生条件
1. iPadでのみ起こる
2. キャンセル時にのみ発生(共有シートの外をタップしたり、ファイルに保存 > キャンセルを選択するなど)
不具合
1. 親のUIViewControllerのdismissメソッドが勝手に呼ばれる
2. 実際にはdismissしない(dismissメソッドをオーバーライドして別の処理を追加していたため不具合が顕在化した)
ワークアラウンド
上記のstack overflowの記事の回答をひとつを参考にしました。
透明のUIViewControllerを生成して、その上にUIActivityViewControllerを表示します。そして、UIActivityViewControllerの完了ハンドラ内で透明のUIViewControllerをdismissします。
完了ハンドラ内でdismissするだけでほとんどのケースは問題なかったのですが、なぜか「マークアップ > PDFを削除」のフローの場合だけ、dismissを呼んでも残り続けたので、さらにdismissの完了ハンドラ内でdismissを呼んでいます。
func onGeneratedPDF(at url: URL) {
let transparentVC = UIViewController()
transparentVC.modalPresentationStyle = .overFullScreen
let acv = UIActivityViewController(activityItems: [url], applicationActivities: nil)
acv.completionWithItemsHandler = { [weak transparentVC] _, _, _, _ in
transparentVC?.dismiss(animated: false, completion: { [weak self] in
if let transparentVC = transparentVC,
transparentVC.presentingViewController == self {
// 「マークアップ > PDFを削除」のフローの場合、ここに来てもVCが残っているので、もう一度呼ぶ
transparentVC.dismiss(animated: false, completon: nil)
}
})
}
present(transparentVC, animated: false, completion: {
let v = transparentVC.view!
acv.popoverPresentationController?.sourceView = v
acv.popoverPresentationController?.sourceRect =
.init(origin: v.bounds.size.toPoint().half, size: .square(0))
transparentVC.present(acv, animated: true, completion: nil)
})
}