0

I am trying to get the name of a UITextField for use in shouldChangeCharactersIn. (I am already using the .tag to hold some other data). I was trying to use this code which I converted to Swift 4:

func propertyName(_ property: Any?) -> String? {
    var numIvars: UInt = 0
    var key: String? = nil
    let ivars: Ivar? = class_copyIvarList(type(of: self), numIvars)
    for i in 0..<Int(numIvars) {
        let thisIvar = ivars[i] as? Ivar
        if (object_getIvar(self, thisIvar) == property) {
            key = String(utf8String: ivar_getName(thisIvar))
            break
        }
    }
    free(ivars)
    return key
}

Which I found here but am getting an error "Cannot convert value of type 'UInt' to expected argument type 'UnsafeMutablePointer?"

My goal is to determine which UITextField is currently selected for editing (I need to limit the max characters based on which field is being edited using shouldChangeCharactersIn).

Thanks in advance.

Update #1: I cannot compare the UITextFields to outlet property because the fields are part of a tableview and dynamically created.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Robert Smith
  • 634
  • 1
  • 8
  • 22
  • 2
    This is the wrong approach. Compare the `textField` parameter to your text field outlets/properties. No need to get the name. – rmaddy Apr 05 '18 at 18:06
  • rmaddy thank you for your input. The fields are dynamically created in a tableview. They are not connected to outlets. – Robert Smith Apr 05 '18 at 18:08
  • 1
    If the text fields are dynamic, you won't have a property for each text field. Why don't you completely rewrite your question explaining the actual problem you need to solve which is going to be about knowing which text field is being edited You'll get better help than asking about problems with the wrong solution to your actual problem. – rmaddy Apr 05 '18 at 18:10
  • rmaddy, I have updated the question with relevant information stating that the fields are dynamically created. – Robert Smith Apr 05 '18 at 18:13
  • No, get rid of the code you posted and replace it with relevant table view code and relevant text field delegate code, etc. Explain your actual base issue. You have no need to get a property name. That's the wrong solution. – rmaddy Apr 05 '18 at 18:20
  • If you're using a tableView, maybe you should access the right cell first, and then try accessing the right textField inside the cell. It should be one of the subviews... – GabrielaBezerra Apr 05 '18 at 18:31

2 Answers2

0

I was able to identify the name of the UITextField when I got to shouldChangeCharactersIn. If anyone has a better way, please post it but this worked perfect for me. Here are the steps to resolve it:

  1. Create a variable global to the view controller to hold the name of the field that is being edited:

    var strCurrentFieldEditing: String = ""

  2. In the cellForRowAt function for the table view, add the event target to handle the Editing Did Begin for each UITextField cell. Set each textfield to call a different function:

    txtFirstName.addTarget(self, action:#selector(self.firstNameEditingDidBegin), for: .editingDidBegin)

    txtLastName.addTarget(self, action:#selector(self.lastNameEditingDidBegin), for: .editingDidBegin)

  3. In the function for each, set the string to the textfield that is being edited:

    @objc func firstNameEditingDidBegin(_ textField: UITextField) { strCurrentFieldEditing = "firstName" }

    @objc func lastNameEditingDidBegin(_ textField: UITextField) { strCurrentFieldEditing = "lastName" }

  4. Now when shouldChangeCharactersIn function is executed, you can determine what field is being edited:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { switch strCurrentFieldEditing { case "firstName": // firstName field is being edited... break case "lastName": // lastName field is being edited... break }

And thats all folks. Of course, if you not using the .tag property, that would be the easiest way, in my case, I was using the .tag property for something else. If anyone has a better/easier way to do this, please post your solution.

Robert Smith
  • 634
  • 1
  • 8
  • 22
0

You can set a name to the property accessibilityIdentifier in the identity inspector > Accessibility.

Then you can use it to know the field you are referring to:

like this=>

if yourTextField.accessibilityIdentifier == "something" {

//do something

}

Alan Silva
  • 139
  • 1
  • 8