iOS开发:UITextField选联系人后号码对应显示异常修复问询
Hey David, I see the issue here—you're not keeping track of which UITextField the user actually tapped, so your code always updates the first one (phonenumber) no matter what. Let's fix this with a few simple changes:
Step 1: Add a variable to track the active text field
First, add an optional UITextField property to your view controller to store the currently selected input box:
var currentActiveTextField: UITextField?
Step 2: Update the active text field when editing begins
Modify your textFieldDidBeginEditing method to set this variable when the user taps a text field:
func textFieldDidBeginEditing(_ textField: UITextField) { currentActiveTextField = textField // Track which field was tapped if !textField.hasText { contactPicker.delegate = self self.present(contactPicker, animated: true, completion: nil) } }
Step 3: Update the correct text field in setNumberFromContact
Change your setNumberFromContact method to use the tracked text field instead of hardcoding phonenumber:
func setNumberFromContact(contactNumber: String) { var cleanedNumber = contactNumber.replacingOccurrences(of: "-", with: "") cleanedNumber = cleanedNumber.replacingOccurrences(of: "(", with: "") cleanedNumber = cleanedNumber.replacingOccurrences(of: ")", with: "") guard cleanedNumber.count >= 10 else { dismiss(animated: true) { self.presentAlert(alertTitle: "", alertMessage: "A valid phone number must have at least 10 digits", lastAction: nil) } return } // Use the tracked active text field instead of the first one currentActiveTextField?.text = String(cleanedNumber.suffix(10)) }
Full Modified Code
Here's how your updated view controller code will look with all changes:
@IBOutlet weak var phonenumber: UITextField! @IBOutlet weak var phonenumber1: UITextField! @IBOutlet weak var phonenumber2: UITextField! // Add this variable to track the active text field var currentActiveTextField: UITextField? func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) { let phoneNumberCount = contact.phoneNumbers.count guard phoneNumberCount > 0 else { dismiss(animated: true) // Show pop up: "Selected contact does not have a number" return } if phoneNumberCount == 1 { setNumberFromContact(contactNumber: contact.phoneNumbers[0].value.stringValue) } else { let alertController = UIAlertController(title: "Select one of the numbers", message: nil, preferredStyle: .alert) for i in 0..<phoneNumberCount { let phoneAction = UIAlertAction(title: contact.phoneNumbers[i].value.stringValue, style: .default) { _ in self.setNumberFromContact(contactNumber: contact.phoneNumbers[i].value.stringValue) } alertController.addAction(phoneAction) } let cancelAction = UIAlertAction(title: "Cancel", style: .destructive) alertController.addAction(cancelAction) dismiss(animated: true) self.present(alertController, animated: true) } } func setNumberFromContact(contactNumber: String) { var cleanedNumber = contactNumber.replacingOccurrences(of: "-", with: "") cleanedNumber = cleanedNumber.replacingOccurrences(of: "(", with: "") cleanedNumber = cleanedNumber.replacingOccurrences(of: ")", with: "") guard cleanedNumber.count >= 10 else { dismiss(animated: true) { self.presentAlert(alertTitle: "", alertMessage: "A valid phone number must have at least 10 digits", lastAction: nil) } return } // Update the active text field instead of hardcoding phonenumber currentActiveTextField?.text = String(cleanedNumber.suffix(10)) } func contactPickerDidCancel(_ picker: CNContactPickerViewController) { } extension SelfTestTimer: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } func textFieldDidBeginEditing(_ textField: UITextField) { currentActiveTextField = textField // Track the tapped field if !textField.hasText { contactPicker.delegate = self self.present(contactPicker, animated: true, completion: nil) } } }
Key Notes:
- I renamed
contactNumbertocleanedNumberin the set method for clarity - Fixed the loop in the alert to use
0..<phoneNumberCountinstead of0...phoneNumberCount-1(more idiomatic Swift) - Updated the error message to be more accurate (your original message said "A maximum of 10 contacts allowed per session" which didn't match the check for number length)
This should now correctly populate the phone number into whichever UITextField the user tapped before opening the contact picker.
内容的提问来源于stack exchange,提问作者David

