The behavior you described is correct, because the implemented delegate allows you only one mode. If you try to implement both single and multiple contact selection at the same time, you will get a warning at run time. And this is exactly your case.
[CNUI WARN] Both single contact and multiple contacts delegate methods
are implemented, the single variants will be ignored
If you want to choose between them, then you need two delegates implementations, one for single selection and another one for multiple selection. Please checkout the solution below:
import UIKit
import ContactsUI
class ViewController: UIViewController {
private var singleSelectionDelegate = SingleSelectionDelegate()
private var multipleSelectionDelegate = MultipleSelectionDelegate()
var isMultipleSelectionAllowed = false
var selectionDelegate: (SelectionDelegate & CNContactPickerDelegate) {
return isMultipleSelectionAllowed ? multipleSelectionDelegate : singleSelectionDelegate
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
singleSelectionDelegate.onContactsSelected = didSelect(contacts:)
multipleSelectionDelegate.onContactsSelected = didSelect(contacts:)
}
@IBAction func onVerify() {
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = selectionDelegate
contactPicker.displayedPropertyKeys = [CNContactGivenNameKey, CNContactPhoneNumbersKey]
self.present(contactPicker, animated: true, completion: nil)
}
@IBAction func onConditionsChanged(segmentedControl: UISegmentedControl) {
isMultipleSelectionAllowed = segmentedControl.selectedSegmentIndex == 1
}
func didSelect(contacts: [CNContact]) {
print("current mode is \(isMultipleSelectionAllowed ? "'single selection'" : "'multiple selection'")")
print("selected contacts = \(contacts)")
}
}
class SelectionDelegate: NSObject {
var onContactsSelected: (([CNContact]) -> Void)?
}
class SingleSelectionDelegate: SelectionDelegate, CNContactPickerDelegate {
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
onContactsSelected?([contact])
}
}
class MultipleSelectionDelegate: SelectionDelegate, CNContactPickerDelegate {
func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
onContactsSelected?(contacts)
}
}
Now there are two delegates and you switch between them depending on your conditions.