Swift - How can I identify which custom tableview cell has been modified? - ios

I have three custom cell types - a cell with a text field, another with a date field, and another with a picker field.
I'm capturing data changes here:
func textFieldDidEndEditing(_ textField: UITextField) {
print("TextField did end editing method called")
switch segmentedControl.selectedSegmentIndex {
case 0:
currentItem.setObject(itemName, forKey: "itemName")
.....
currentItem.setObject(serialNumber, forKey: "serialNumber")
break
case 1:
currentItem.setObject(username, forKey: "username")
currentItem.setObject(email, forKey: "email")
...
break
The "currentItem" is a CKRecord.
This is wrong. The fields (itemName, serialNumber, etc) are strings. They are set in ViewDidLoad with cloud data.
How do I correctly update these fields
Thanks in advance

As Subin K Kuriakose has said in the comments, you should use the tag property of UITextField to figure out which text field it is.
You need to set the tag property when you create the text field cell. Just keep a variable somewhere and increment it each time a text field is created, and set the tag to this variable:
textFieldCount += 1
myCustomCell.textField.tag = textFieldCount
Something like that, you get the idea.
Now each text field in your table view has a unique tag. In textFieldDidEndEditing, you check the tag:
switch textField.tag {
case 1:
// it's the first text field!
case 2:
// it's the second text field!
case 3:
// it's the third text field!
default:
break
}
It's simple!

Related

Wanting to return index of first Responder in swift when tapped but order is weird

I have 100 UITextField boxes in storyBoard which are stored in an array called boxArray.
I also have another array called importantIndexes, which stores important indexes of boxArray.
(Bear with me on this on this next paragraph)
When a user taps on a specific UITextField box in boxArray who's index matches a value in the importantIndexes array. I then want to return the index of importantIndexes array which value is the index of the boxArray first responder.
This is the function that gets called when one of the specific UITextField are tapped:
#objc func myNotWorkingFunction(textField: UITextField) {
for i in 0...99 {
if (boxArray[i]?.isFirstResponder)! {
let index = boxArray.index(of: boxArray[i])
print(index)
}
}
}
I'm running into two problems. The first is that the print function is returning "Optional(Index)". I just want the int value Index but it's printing it like this example: Optional(14).
My second problem is that this seems to print the index of first responder of whatever was the first responder before it was changed to the new one. Let's say the user was at 11th boxArray UITextField, then taps on the 55th, the print returns "Optional(11)" instead of just "55" which is what I want.
I can't use textFieldDidEndEditing(:_) here, which would probably work fine. I have to stick with the tapping functionality. Any ideas?
First problem is solved by unwrapping
if let index = boxArray.index(of: boxArray[i]) {
print(index)
}
Second problem 'may' be that you need to call this when your objc function is called.
declare:
var currentTextField: UITextField?
In your function:
currentTextField?.resignFirstResponder()
currentTextField = textField
textField.becomesFirstResponder()

Swift 3 textview. How do you add \n to line breaks when return key is pressed

I created a form and in that form is a textview where user's can type to report problems with the app. The problem is when the user clicks the return key it creates a line break [Line 2. in the image]. The textview text is stored in the text variable and is being passed to a url. I already am using replaceOccurences for spacing in between words. How would add \n to the line breaks created by the return key?
Thanks.
I want the text stored in database to look like this:
This is where text goes. Line break below \n this is after the return key...
#IBAction func send(_ sender: AnyObject){
let text = textView.text!
if(text.isEmpty){ Alert01("Please provide a brief description."); return }
let reportUrl = "http://www.appurl.com/report.php?id=\(userId)&message=\(text)"
let urlEncodedString = reportUrl.replacingOccurrences(of: " ", with: "%20")
parseJSON(url: urlEncodedString) }
}

How to unclear UITextField secure text entry in Swift?

When I use default Security text Entry in UITextField in Swift Language after type type text once UITextField.
Once loss focus from UITextField after try to edit Secure text then UITextField is first reset and after it start put new text in UITextField.
How to edit old Secure Text without Storing data into Any Kind of String object
I'd suggest to create a custom UITextField class and override become​First​Responder() method do add your desired functionality:
You can override this method in your custom responders to update your
object's state or perform some action such as highlighting the
selection. If you override this method, you must call super at some
point in your implementation.
The custom Class should be similar to:
class CustomSecureTextField: UITextField {
override func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true }
if let currentText = text { insertText(currentText) }
return true
}
}
The logic of the implementation of becomeFirstResponder as follows:
By default, the secured-entry text field clears the inserted text when it is become first responder text, so what's happening in CustomSecureTextField that if the text field is secured-entry, it will re-insert the current inserted text -after clearing it-, but you have to make sure that the text field input is secured (that's the purpose of adding if !isSecureTextEntry { return true }) or the text will be duplicated (re-inserted) each time the text field becomes first responder.
Output:
Note that both of text fields are types of CustomSecureTextField:
This answer helped me to figure out this problem.
textField.isSecureTextEntry = true
following property not gonna work if you make testField isSecureTextEntrysecure property makes true .
textField.clearsOnBeginEditing = false
There is an issue with the #Ahmd F solution when you simply tap on the field it will automatically add the text to the field I have resolved that in the below code thanks
override open func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true}
if let currrentText = text {
self.text = ""
insertText(currrentText)
}
return true
}

Swift3: best way to validate the text entered by the user in a UITextField

Evening, in my app I have several UITextfield. Each one has to confirm to different limitations.
For example, I have a date Field, zipCode Field, SSN Field etc.
From the Apple Documentation I found:
Assign a delegate object to handle important tasks, such as:
Determining whether the user should be allowed to edit the text field’s contents.
Validating the text entered by the user.
Responding to taps in the keyboard’s return button.
Forwarding the user-entered text to other parts of your app.
Store a reference to the text field in one of your controller objects.
So I'm pretty sure I have to use delegates and func textFieldDidEndEditing(_:).
The only way that came to my mind is to use a switch statement inside the func textFieldDidEndEditing(_:) to confirm the delegate to the difference limitation.
Is there a better, safer and faster pattern to face this problem?
You can set unique tag to your every text field and can compare in textFieldDidEndEditing or you can take IBOutlet of every textField and can compare it in textFieldDidEndEditing like,
func textFieldDidEndEditing(textField: UITextField) {
// By tag
if textField.tag == 100 {
}
// OR
//by outlet
if textField == self.myTextField {
}
}
You are right, you will have to check the textfield, either you can check tags assigned for different text fields using switch statement like you said,
or you can compare textfields itself,
if textfield1,textfield2 are outlets to two text fields, you can compare as following,
func textFieldDidEndEditing(textField: UITextField)
{
if textField == textfield1
{
}
else if textField == textfield2
{
}
}
you can create enum for validation
enum Type {
case zipcode
case number
}
then you can create a method for validation like this :
func isValidate(text: String, type: Type) -> Bool {
switch type {
case .zipcode:
...
}
}
this method can be in Util class. this is best practice. because your logic is encapsulate from out .
If you need more control over the text which is committed to the text field or if you want to provide feedback while the text field is being edited, you should implement a different delegate instead:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Build and check the new text value. Accept or reject the change.
}
In the delegate, you can build the new text value. Validate it, apply constraints, decide on which feedback the user should receive ("Your password must be at least eight characters long", "This is not a valid IBAN"), accept or reject the change (i.e. return false).
Keep in mind, that the delegate is not called if you assign the text property manually. Moreover, this delegate is called when text is pasted into or deleted from the text field, which can make matters much more complicated depending on what you do.

Value of textfield before "Editing Changed" event is fired

I want to know if there is a way to know the value of textfield before the value is changed to the new value.
For example:
If the text field had a value "a" and the user entered "b", so the editing changed event is fired. When I try to fetch the value of the text field in the debugger it will display "ab". Is there a way that I can get "a" before "b" was written?
Here is a piece of code where I am trying to fetch the value:
#IBAction func commentEditingChanged(sender: AnyObject) {
if(!((sender as? UITextField)!.text!.isEmpty)){
counter++
}
else
{
counter--
}
}
In this case I want to know if the text was empty before the user entered text because I don't want the counter increments every time the user enters a character. I want to increment once the user entered any text.
And please don't propose to use delegate function textField:shouldChangeCharactersInRange:replacementString because my question is about this IBAction method.
If there is no way to do that using this IBAction Method, is there is any other IBAction method that can achieve what i want?

Resources