You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中在CNContactPicker的didSelect方法内无法弹出MFMessageComposeViewController?

Fixing the CA Restriction Error When Presenting a VC from CNContactPicker's didSelect

Hey there! That error message you're seeing is super common when trying to present a new view controller right from the didSelect callback of CNContactPickerViewController—let me break down why it happens and how to fix it quickly.

Why the Error Occurs

The CNContactPickerViewController is a system-provided UI component. When you select a contact, the picker is in the middle of its dismissal transition (the "pre-commit handler" mentioned in the error). Core Animation has a restriction here: you can't add new view hierarchy changes (like presenting another VC) while the system is still wrapping up the picker's own transition animations. It's like trying to start a new task before the previous one has fully finished!

Solution 1: Delay the Present Operation (Simplest Fix)

The easiest way is to push your present call to the next run loop cycle using DispatchQueue.main.async. This gives the picker enough time to finish its dismissal before you present your message VC:

func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
    // First, process your selected contact data here
    // (e.g., extract phone numbers/emails to pass to messageVC)
    
    // Delay the present until the picker's transition completes
    DispatchQueue.main.async {
        self.present(self.messageVC, animated: true, completion: nil)
    }
}

Solution 2: Explicitly Dismiss the Picker First

If you want more control over the timing, you can explicitly dismiss the picker and present your VC in the dismissal completion block. This ensures the picker is fully gone before your message VC appears:

func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
    // Process contact data first
    
    // Dismiss the picker, then present messageVC in the completion
    picker.dismiss(animated: true) {
        self.present(self.messageVC, animated: true, completion: nil)
    }
}

Note: This works best if you presented the contact picker (the most common use case). If you pushed it onto a navigation stack, you'd use picker.navigationController?.popViewController(animated: true, completion: ...) instead.

Quick Check

Make sure your messageVC is properly initialized (not nil) and hasn't already been presented elsewhere—those issues can cause secondary problems, but the core error you're seeing is definitely about timing.

内容的提问来源于stack exchange,提问作者Marko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:40:46