I have a text field where I want to insert a phone number. The problem is that I use number pad and there is not any enter key and I without that key I don't know how to close the text field.
Is there any way of checking how many number os characters there are in a text field and close the number pad when there are X chars?
Sorry for my english and sorry for the noob question but I am just starting with ObjC.
Thanks *
Sorry guys, I forgot to tell you that I already have tried this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length== 9) {
[textField resignFirstResponder];
}
return YES;
}
Yes, you have two choices in my opinion, you can:
A. Check the number of chars returned in delegate method shouldChangeTextInRange and then if your limit is reached resign first responder (when you resign first responder the keyboard dismisses,
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ( textView.text.length + (text.length - range.length) == 10) //or whatever value you like
{
[textField resignFirstResponder];
}
}
Or B:
Override the touchesEnded method of your view and call resignFirstResponder, so that when the user touches the view outside the textField, the keyboard dismisses. - this is what I do in my app.
Like this:
Just add this method to your viewController, it will be called automatically when the touch in the view ends, in this method you simply resignFirstResponder and the keyboard will disappear.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
}
I think it's better to do this in touchesEnded than began, it 'feels' nicer to have the keyboard dismiss when you lift your finger from the view, rather than when to initially touch it.
I found that resignFirstResponder do not include the last char typed. I had to do it in this way,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
DLog(#"Existing: %#, string: %#, range:(%lu, %lu)", textField.text, string, (unsigned long)range.location, (unsigned long)range.length);
if (textField == field2.textField) {
if ( textField.text.length + (string.length - range.length) == kMyNumberLength) // e.g. 10
{
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
[textField resignFirstResponder];
}
if (textField.text.length + string.length - range.length > kMyNumberLength) {
return NO;
} else {
return YES;
}
}
return YES;
}
Swift
when reaching the maximum number of characters, add the new char to the current text in the textfield and then dismiss the keyboard
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 5
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
if newString.length == maxLength {
textField.text = textField.text! + string
textField.resignFirstResponder()
}
return newString.length <= maxLength
}
Every time a user adds a number, the delegate of your text field will be notified through this method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger length = [[textField text] length] - range.length + string.length;
if (length == ...) ...
}
You can set up your delegate in such a way as to watch the length of the modified content of your text field, and close the field when the expected length is reached.
However, this has a high potential to frustrate your users a lot: they would make a mistake entering the last character every now and then, and the field is going to close on them, not letting them correct the problem. A better approach is to dismiss the pad when users tap away from your text field, which keeps end-users in control of what is going on:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
}
You can just put a toolbar with a Done on it, on the click on that button you can hide keyboard and toolbar as well.
-(IBAction)doneButtonClicked:(id)sender{
[yourTextField resignFirstResponder];
[toolBar setHidden:YES];
}
or you can use this custom tool
Had issues with some of the suggestions above not retaining the last character entered.
I found this worked well for me.
Method simply examines the length of the text as it is building up and then runs [textField resignFirstResponder] to dismiss.
All usual textField delegates will run for the textField at point field loses focus and keyboard is dismissed.
- (void)textFieldDidChangeSelection:(UITextField *)textField {
NSLog(#"textField.text: %#", textField.text);
if (textField.text.length == 4) // If 4 is your max-length
[textField resignFirstResponder];
}
Use this textfield delegate method to find out the length of textField.text
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int textLength = [textField.text length] + 1;
return YES;
}
Related
I am having 3 textfields and I have restricted character limit to 50 for each textfield using UITextFeildDelegate method and it is working fine. Now when I try to input text through speech and not by keyboard then the textfield seems to accept more than 50 characters and some time the whole text disappear when the speech input is completed.
Here is my delegate method shouldChangeCharactersInRange
if(textField==self.optionATextField || textField==self.optionBTextField ||textField==self.optionCTextField) {
if(range.length + range.location > textField.text.length) {
return NO;
}
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return newLength <= 50;
}
Is there any way to do it? Do I need to implement any other method for speech input to work properly.
Hope you understand the problem.
Thanks in advance
shouldChangeCharactersInRange , override method won't be called when user is using dictation(Speech To Text) function.
What you can do is,(This example is on C#(Xamarin iOS))
1.Use :
textField.EditingChanged += textField_EditingChanged;
2.Inside the below method implement following,
maxLength: Max length for searchBar textfield
private void textField_EditingChanged(object sender, EventArgs e)
{
var textField = sender as UITextField;
var maxLengthSubstractionValue = textField.Text.Length.CompareTo(maxLength);
if(maxLengthSubstractionValue == 1)
{
textField.Text = textField.Text.Substring(0, Math.Min(maxLength, textField.Text.Length));
}
}
To implement the functionality, you have to use textViewDidChange delegate method.
- (void)textViewDidChange:(UITextView *)textView {
if (textView.text.length > kMaxCharAllowed) {
textView.text = [textView.text substringToIndex:kMaxCharAllowed];
}
}
This method will be called whenever there is a change in text field string. We replace the text with a string of the desired length if the text is lengthier than desired.
Along with this, use - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text method to handle the keyboard inputs.
Assuming you want the entered text to be truncated to a maximum of 50 characters regardless of the method of entry, you can do something like this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if(textField==self.optionATextField || textField==self.optionBTextField ||textField==self.optionCTextField) {
NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (newText.length < 50) {
// Text length is still OK, let it through
return YES;
} else {
// The new text is too long - truncate and set the shorter value
newText = [newText substringToIndex:50];
textField.text = newText;
return NO;
}
} else {
return YES; // do whatever you need here
}
}
I have an app that needs to include a field where the user can input a decimal scalar number. Is there a recipe for how to accomplish this? I've read the relevant parts in Matt Neuburg's "Programming iOS 7" book. I've tried a Cocoapod (MPNumericTextField). I'm not having a lot of luck...
What I've accomplished so far:
Painted a UITextField in my storyboard.
Given it an outlet and a delegate.
Set its Keyboard Type to Decimal Pad.
Implemented the following 3 methods:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
NSLog(#"textFieldShouldEndEditing:");
[textField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(#"textFieldShouldReturn:");
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(#"textFieldDidBeginEditing:");
[textField selectAll: nil];
}
It appears that I'll have to implement textField:shouldChangeCharactersInRange:replacementString: method to avoid duplicate decimal points being put in.
But I can't figure out how to dismiss/close the keyboard when I'm done inputting the number. What's the point of the Decimal Pad if you can't close it?
Are there other things I have to do get a simple numeric field working?
Following line of code might serve your need
[self.view endEditing:YES];
You will need to implement delegate like this to scan number and avoid double . in value.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == _amountField) {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] == 0)
{
return YES;
}
double holder;
NSScanner *scan = nil;
scan = [NSScanner scannerWithString: newString];
return ([scan scanDouble: &holder] && [scan isAtEnd]);
}
return YES;
}
I have one UiTextField Called MobileNumber. and two pickerView called Operator and circle. When I enter first 4 digits of my number in textfield it displays the Operator pickerview,
how to call it when I enter first 4 digits value in textfield and display the pickerview
Use shouldChangeCharactersInRange textField's delegate method for entering numeric character
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
{
//This field accepts only numeric entries.
return NO;
}
else //numeric value entered
{
NSString *strTxtField = [textField.text stringByAppendingString:string];
if(strTxtField.length == 4)
{
//show pickerview here
//Set return NO if you don't want more character to be added to textfield
//return NO;
}
return YES;
}
}
You can declare a notification that will be called on every single change in text field.
// Add a "textFieldDidChange" notification method to the text field control.
[textField addTarget:self
action:#selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
Now here on this method textFieldDidChange: you can access your text field and check if user has entered 4 digits you can show the picker.
try this code...
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(newString.length == 4)
{
NSLog(#"show date picker");
//Set return NO if you don't want more character to be added to textfield
//return NO;
}
return newString.length <= 4;
}
make sure that your text field delegate set properly..
I am making a simple application that has a TextField and a TextView
Whatever we write in textfield will get updated in textview (Both are in a single View, and it is the Root view).
the textfield will get updated every time i hit any key in the keyboard.
I know that the delegate method "textfielddidEditing" helps , but it only helps when we click on the field or click back. I want the method that invokes every time when i hit anything in the keyboard.
Any help is appreciated.
I'm still learning iOS
Please use below textfield delegate method. Its easy and simple to use with all appen and delete mechanism. You can delete multiple characters too by selection. Just store newString value to your textView
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSMutableString *newString = [NSMutableString stringWithString:textField.text];
if (range.length > 0) {
[newString replaceCharactersInRange:range withString:string];
}
else {
[newString appendString:string];
}
NSLog(#"%#",newString);
return YES;
}
You can use UITextField Delegate method. It invokes every time when you hit anything in the keyboard. Write your code as per your requirement..
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length>0)
{
self.yourtextview.text=textField.text;
}
return YES;
}
Hope it helps you..
The above code mentioned by Vidhyanad900 will work. But its if would fail in case a user deletes the text. (Hits backspace or selects complete text and deletes it)
Hence Modifying the code
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int iNewLength = [textField length];
if([text isEqualToString:#""]) //If text is deleted
{
if([textField selectedTextRange]) //If Text is Seleceted And Deleted
iNewLength = [textField length] - [textField selectedRange].length;
else
iNewLength = [textField length] - 1;
}
if (iNewLength > 0)
{
self.yourtextview.text=textField.text;
}
return YES;
}
I am writing validation for my textfield, I found something interesting that whether I can check how many digits I am typing into the textfield at real time. My text field input must be 8 digit number. So I want to change the text inside the text field to green colour when I reach 8 digit and change colour when it's not.
How can I do that? Please help me, thanks in advance.
Using -textField:shouldChangeCharactersInRange:replacementString: is probably a bad solution because it fires before the text field updates. This method should probably be used when you want to change the text of the text field before the keyboard automatically updates it. Here, you probably want to simply use target-action pairing when editing value changes:
[textField addTarget:self action:#selector(checkTextField:) forControlEvents:UIControlEventEditingChanged];
Then, in - (void)checkTextField:(id)sender, try this:
UITextField *textField = (UITextField *)sender;
if ([textField.text length] == 8) {
textField.textColor = [UIColor greenColor]; // No cargo-culting please, this color is very ugly...
} else {
textField.textColor = [UIColor blackColor];
/* Must be done in case the user deletes a key after adding 8 digits,
or adds a ninth digit */
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
// [textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];
NSLog(#"%#",searchStr);
return YES;
}
Use UITextFieldDelegate. especially this function
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
and you can get sample codes links from here..
[textField addTarget:self action:#selector(checkTextField) forControlEvents:UIControlEventEditingChanged];
Try it!
Set up a delegate for the UITextField and implement the method – textField:shouldChangeCharactersInRange:replacementString: Details and examples are in the UITextFieldDelegate Protocol Reference, but here's a quick example:
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
NSString *text = [textField text];
// NOT BACKSPACE
if ([string length] || text.length + string.length < 8) {
return YES;
} else if (text.length + string.length > 8) {
return NO;
} else {
// DO SOMETHING FOR LENGTH == 8
return YES;
}
}
Update Swift 4.0
txtFieldAdd.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
Now call your function. In my case, this will enable the save button
#objc func textFieldDidChange(_ textField: UITextField) {
if (txtFieldAdd.text?.isEmpty)! {
btnSave.isEnabled = false
}
else {
btnSave.isEnabled = true
}
}
Hope it helps.
This is how you get realtime validation without setting up anything other than the delegate of the textfield:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Creating the future string. The incoming string can be a single character,
// empty (on delete) or many characters when the user is pasting text.
let futureString: String = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
// Determine if the change is allowed, update form, etc.
let allowChange = <#Your Validation Code#>
return allowChange
}
Add this code to the designated delegate of the textfield. Simple.