Getting the Value of a UITextField as keystrokes are entered? - ios

Let's say I have the following code:
IBOutlet UITextField* nameTextField;
IBOutlet UILabel* greetingLabel;
I'd like the greetingLabel to read "Hello [nameTextField]" as soon as the user presses any key.
What I need basically is the iPhone equivalent of the Cocoa delegate method controlTextDidChange.
The textField:shouldChangeCharactersInRange: delegate method is called each time a keystroke occurs:
- (BOOL) textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
The string argument returns the character that is pressed. The actual textField's value (nameTextField.text) remains blank however.
What am I missing here? (I'd like nameTextField to reflect the exact string that the user has entered so far).

It turns out, the easiest way to do this is using Interface Builder:
Add a IBAction (to the ViewController, say, as in this case)
Ctrl-Click (or right click) on the UITextField in Interface Builder
Connect the "Editing Changed" event to the File's Owner's IBAction added in the first step.
Works like a charm :) (I can't believe I spent numerous days on this, and to realize now that the solution was much simpler than I'd thought :P)

you could register an action for the event UIControlEventEditingChanges on the text field:
[nameTextField addTarget:self action:#selector(updateLabelUsingContentsOfTextField:) forControlEvents:UIControlEventEditingChanged];
...
// TODO: error checking
- (void)updateLabelUsingContentsOfTextField:(id)sender {
greetingLabel.text = [NSString stringWithFormat:#"Hello %#", ((UITextField *)sender).text];
}

UITextField has a notification UITextFieldTextDidChange which will be fired every time the text changes if you register for it. Just register for that notification and in the method called by the notification, change the label's text.
To add to this, the object passed to your notification handler will have the text of the UITextField.
Hope that helps.

Related

Implement a autocomplete textfield Objective C

I am starting to work with text fields, and I want to implement a functionality with a custom autocomplete.
In a lot of blogs and answer, implement it with UITables to show the autocomplete, but I do not need this, I need to create a autocomplete like a iPhone function, where show a pop out with the filter but only with my array of words.
For example.
my_array = #{"apple","banana","pear","orange","berry"}
When I type "app" the text field only need to show me "apple" but not complete the text in the text field, should show the pop up with the autocomplete.
Something like this but only with my array.
You can build this behaviour yourself using the UITextFieldDelegate methods
( implement the delegate in your UIView
#interface someViewController : UIViewController <UITextFieldDelegate>
In doing this you get access to whatever the user has typed in
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Where you can compare it to the items in your array and display another UIView or a custom button that when selected populates your text field.
Don't forget to tell your textfield who it's delegate should be, probably in your viewDidLoad method, but can also be done in the xib view
myTextField.delegate = self;
I know this seems laborious but it will be extremely gratifying.
Here's the apple doc for the UITextViewDelegate
I've implemented a custom auto complete textfield few days ago and the raywenderlich tutorial was helpful.
http://www.raywenderlich.com/336/auto-complete-tutorial-for-ios-how-to-auto-complete-with-custom-values
You probably need to implement your own table view to make it look like the screen you attached. The short tutorial will give you an idea how it should be done. I will post my code tomorrow if you want.

UITextField Number formatter when setting or editing text

I have UITextField that I have formatting code attached on textFieldDidEndEditing:. This works fine, but when I first load the text field with a text value (someTextField.text = #"...") the formatting doesn't happen. Of course, I can add another formatter there, but it seems kind of repetitive.
Is there a way to make all changes to a UITextField, programmatic or user originated, have formatting applied automatically?
Just run the same method from both places...
- (void)setTextFieldWithText:(NSString *)text {
//do formatting here...
self.textField.text = formattedText;
}
You can either add UITextFieldDidChangeNotification or just add a observer(using the addObserver method) to observe changes to the textfield. Choose which suits your approach. Both of them does cut the repetitive code. KVO - concept related to your question.
you might get some idea if you take a look at the following links
UITextFieldDidChangeNotification - How do i notify changes in UITextField?
addObserver method - detecting the change of content of UITextField when the change is not made by the keyboard
Note: Although the classes of the UIKit framework generally do not support KVO, you can still implement it in the custom objects of your application, including custom views.

I want to save the text in uitextfields when navigating between view controllers

I have an ipad app that has a series of viewcontrollers each with a set of uitextfields. Basically what I want to be able to do is when navigating through the different viewcontrollers, I want the text to remain in each uitextfield that has been edited. What happens now is when I leave a certain viewcontroller and come back to it, each uitextfield is empty. To fix this would I call the viewWillDisappear or viewDidDisappear methods? And if so, how would I make it save the information within each textfield?
Are you just doing modal segues? When you want to return back to the previous view, just use the [self dismissViewControllerAnimated:YES completion:nil] and everything previously filled in will still remain. It's only if you segue back to the initial view that the text will not be there anymore. However, if you need to segue back to the initial view for some reason, you can just save the text to the NSUserDefaults, and then populate the field with the value saved on viewWillAppear. It's better practice to always dismiss viewControllers rather than doing circular segues though.
You could abuse the shouldChangeCharactersInRange method and save the characters typed in so far to an extra string and restore it after switching viewcontroller.
Update
For each textfield in a view you need set up a saveString and associate it, maybe make the tag value as array index, then you could to this:
add <UITextFieldDelegate> the class' interface definition
set the delegate for each textfield to self
add this method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *s = [textField replaceCharactersInRange:range withString:string];
NSLog(#"current textfield value '%#'", s);
// save s somwhere, e.g. to userdefaults or a DB table
return YES;
}
Now after you've switched to back to a previous view, you can restore each textfield's previous contents. I've put in the NSLog() so you can see when this method is called.

IOS textFieldDidChange when outlet in other class

I've got a specific iOS question when accessing an outlet on a different class.
In my project I have a UItableView with custom tableViewCells which I have created using the interface builder. These cells have UItextfields on them and I need to know when a value of a certain textfield is changed. (so I can add a new empty cell with textfield, just like in your address book) I came across the following function
[UITextfield addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
The problem is that I use this function in the main class when the outlet of the textfield is in the subclass (specific tableViewCell class).
I Created an Method of the outlet so I could access it in the main class. But still is above code does not trigger the textFieldDidChange event.
Hope someone could help me with this problem. Or give me a different solution to achieve my goal (creating an new empty textfield when adding the first character to the current UITextfield).
Thnx
textFieldDidChange doesn't work. Well, I had a lot of problems with it.
I don't know if it's deprecated or something.
Either way you can use shouldChangeCharacterInRange almost same way as long as it's delegated correctly.
But you have to modify it a bit because the method is triggered before you actually typed something. So you have to get the new value and add it yourself.
- (BOOL) textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Check the replacementString
return YES;
}

How to pass 2 parameters in Objective-C

In iOS application development, how do I pass 2 parameters to login button?
I want to pass username and password on the button click of login button.
I have given in this manner:
-(IBAction)Login_Method:(id)sender withpassword:(id)password
{
}
It is not possible to send 2 parameters in an IBAction method.
What you can do is
Create 2 outlets and then connect these to password and username textfields.
On Clicking the login button, read the text value from the above 2 outlets.
Your login button action method will be like this
//username and password are UITextfields
-(IBAction)Login_Method:(id)sender
{
id name=[username text];
id pass=[password text];
}
As far as I know, IBActions are defined this way:
- (IBAction) actionMethod:(id)sender
Unless your button is subclassed much differently than usual, it is not going to call IBAction with an extra parameter (your withpassword: password).
You will have to use the standard definition above, get the call from the UIButton, and then get the text from your fields and then you can pass that to another method that will do the login with those two fields - unrelated to the UIButton's IBAction.
Typically, when you link a UIButton to a method in Interface Builder, that method will have no parameters. Technically, it can have zero, one, or two. The first is the sender (the button that was tapped) and the second is the event (the tap).
See the target-action mechanism for controls:
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
Also, you will typically link user inputs (such as UITextField instances) as IBOutlets. Then, you can access the user input through the text property:
// in your interface (header file):
IBOutlet UITextField *userNameTextField;
// in your implementation file:
NSString *userName = userNameTextField.text;
Finally, you should use correct types. Usernames and passwords are probably NSString* (pointers to NSString objects). "id" is the generic type and is not necessary here.

Resources