textField:shouldChangeCharactersInRange:replacementString: isn't called when inputing in a UITextField - ios

I have a UITextField and I want it has a maximum text length of 20. So I let self(the current view controller) agree to <UITextFieldDelegate> and set self as the text field's delegate, and use the following method to set a maximum length:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.nickNameTextField)
{
if (textField.text.length > 20)
return NO;
}
return YES;
}
However when I insert a breakpoint in this function I found that this function wasn't called when I typed in any words, much less when the text's length exceeds 20. Can somebody tell me why?

You probably haven't linked your textfield with the delegate
Right click on textField which you want to have delegated and drag the textField on the viewcontroller and drop to select the delegate.

I show you steps and screenshot for connecting textField and delegate with XIB or Storyboard.
In storyboard
STEP 1: Click the TextField
STEP 2: Drag the TextField to ViewController
STEP 3: Click "control+mouse" on TextField to ViewController.h and line shows
STEP 4:Now Box will appear and give the TextField Name
STEP 5:Right Click the TextField in ViewController
STEP 6:Hook Up the Delegate to ViewController
If you want to programmatically create the textField
UITextField *txtfldMaxLength = [[UITextField alloc] initWithFrame:CGRectMake(30, 100, 250, 50)];
txtfldMaxLength.borderStyle = UITextBorderStyleRoundedRect;
txtfldMaxLength.textColor = [UIColor blackColor];
txtfldMaxLength.backgroundColor = [UIColor clearColor];
txtfldMaxLength.font = [UIFont systemFontOfSize:17];
txtfldMaxLength.placeholder = #"enter something";
txtfldMaxLength.autocorrectionType = UITextAutocorrectionTypeNo;
txtfldMaxLength.keyboardType = UIKeyboardTypeDefault;
txtfldMaxLength.returnKeyType = UIReturnKeyDone;
txtfldMaxLength.clearButtonMode = UITextFieldViewModeWhileEditing;
txtfldMaxLength.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
txtfldMaxLength.delegate = self;
[self.view addSubview:txtfldMaxLength];

Well I've figured out the problem. I use this grammar to instantiate a UITextField:
self.nickNameTextField.delegate = self;
self.nickNameTextField = ({
UITextField *textField = [UITextField new];
textField.placeholder = [BBTCurrentUserManager sharedCurrentUserManager].currentUser.nickName;
textField.textAlignment = NSTextAlignmentLeft;
textField.backgroundColor = [UIColor lightGrayColor];
textField;
});
Originally I set the textField's delegate outside the braces(like the code above). But when I move self.nickNameTextField.delegate = self;inside the braces then it worked. However I have no idea about why this happened, can someone tell me why?

Related

How do I program text into textfield?

I am using Xcode 6.3 with Objective-C language. The app that I am building has UITextField and UITextView. I am wanting to have text show up in the fields/views so that the user will have instructions on what to put into the fields/views. Example, "enter your name". How can I do this?
UITextField:
For your UITextField you should define the placeholder for the instructions text.
_textField.placeholder= #"Your Name";
UITextView :
UITextView does not have a default placeholder like UITextField.
But you can make the effect like placeholder by following these steps.
- (void)viewDidLoad {
[super viewDidLoad];
_textView.text = #"Enter Comment...";
_textView.textColor = [UIColor lightGrayColor];
_textView.delegate = self;
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#"Enter Comment..."]) {
textView.text = #"";
textView.textColor = [UIColor blackColor];
}
[textView becomeFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#""]) {
textView.text = #"Enter Comment...";
textView.textColor = [UIColor lightGrayColor];
}
[textView resignFirstResponder];
}
You may be looking for the placeholder property.
let t = UITextField()
t.placeholder = "enter your name"
if you wann change the text just call:
textfield.text = #"enter your name"
if you just want to set a placeholder which will disappear on user input use this property :
textfield.placeholder = #"enter your name"
if you want a list instructions , please add /place a UIView in appropriate location and show and hide inside your textFieldDidBeginEditing: delegate method.
Note :- place holders might not be appropriate as it has limit to text and your instructions may be huge.
Place holders for text fields is the way you can have some text shown...
textField.placeholder = "Enter your name"

UITextField action - change SKLabelNode

I am using Objective-C to make an iOS SpriteKit "GameScene" file.
I have an SKLabelNode and a UITextField to input a player's name.
How can I make whatever the UITextField value equals to change the SKLabelNode to say "Thanks," + UITextField value?
(my code) :
#import "GameScene.h"
#implementation GameScene
-(void)didMoveToView:(SKView *)view {
// Use Objective-C to declare all SpriteKit Objects
// inside the {parameters} of "didMoveToView" method:
// SKLabelNodes (SpriteKit Object) display "text".
// Objective-C object named *winner = SKLabelNode (SpriteKit Object)
SKLabelNode *winner = [SKLabelNode labelNodeWithFontNamed:#"Tahoma"];
winner.text = #"You Win!";
winner.fontSize = 65;
winner.fontColor = [SKColor blueColor];
winner.position = CGPointMake(500,500);
[self addChild:winner];
// UITextFields (SpriteKit Object) allow "text" input from users.
// Objective-C object named *textField = UITextField (SpriteKit Object)
UITextField *textField = [[UITextField alloc]
initWithFrame:CGRectMake(self.size.width/2, self.size.height/2+20, 200, 40)];
textField.center = self.view.center;
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.textColor = [UIColor blackColor];
textField.font = [UIFont systemFontOfSize:17.0];
textField.placeholder = #"Enter your name here";
textField.backgroundColor = [UIColor whiteColor];
textField.autocorrectionType = UITextAutocorrectionTypeYes;
textField.keyboardType = UIKeyboardTypeDefault;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
[self.view addSubview:textField];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
#end
You need to use a delegate method. Specifically
- (void)textFieldDidEndEditing:(UITextField *)textField;
to do this when you create your textFeild add this line of code
[textfield setDelegate:self]
also to add in that you fallow the delegate in you .h file
#interface ViewController : UIViewController <UITextFieldDelegate>
then when that code gets called you would say inside the method
SKLabelNode = [NSString stringWithFormat:#"Thanks %#",textField.text]

How do I centre UITextField cursor after user input consistently

I have a UITextField that I want to centre all content (text, cursor) at all times. Is this possible in iOS 7? My current initialisation of the view is shown below.
self.textField = [[UITextField alloc] init];
self.textField.delegate = self;
[self.textField setTextAlignment:NSTextAlignmentCenter];
self.textField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
self.textField setTranslatesAutoresizingMaskIntoConstraints:NO];
self.textField.placeholder = NSLocalizedString(#"Enter some text", #"The placeholder text to use for this input field");
My requirement for this is that when I click in the UITextField, the placeholder text should disappear, and show the cursor in the middle of the UITextField.
Currently, this seems to be intermittently positioned either in the middle of the text field or on the left of the text field irrelevant of where I click. Anybody got any suggestions as to how I can solve this or is it a known issue in iOS?
If you're creating you UITextField in you Storyboard you should not initialise and alloc it in code.
You need to use you Textfield delegates to accomplish this..
- (void)viewDidLoad
{
[super viewDidLoad];
self.textField.delegate = self;
[self.textField setTextAlignment:NSTextAlignmentCenter];
self.textField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
[self.textField setTranslatesAutoresizingMaskIntoConstraints:NO];
self.textField.placeholder = #"Enter some text";
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
//this removes your placeholder when textField get tapped
self.textField.placeholder = nil;
//this sets your cursor to the middle
self.textField.text = #" ";
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
self.textField.placeholder = #"The placeholder text to use for this input field";
}
This surely does the trick.. Please accept the answer if it helps.
UPDATE
With code below when user press backspace the cursor will not align the text to the left.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *proposedNewString = [[textField text] stringByReplacingCharactersInRange:range withString:string];
NSLog(#"propose: %#", proposedNewString);
if ([proposedNewString isEqualToString:#""])
{
textField.text = [#" " stringByAppendingString:textField.text];
}
return YES;
}

UITextfield in a Grouped UITableViewCell

I am trying to implement an input form on an iPhone app by using a grouped static table view.
I'm using didSelectRowAtIndexPath to lazily create a textfield and add to the relevant cell.
My problem is that becomeFirstResponder is not behaving as I would expect.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
if(!self.contactNameTextField)
{
self.contactNameTextField = [[UITextField alloc] initWithFrame:CGRectMake(93, 14, 200, 20)];
self.contactNameTextField.backgroundColor = [UIColor clearColor];
self.contactNameTextField.font = [UIFont boldSystemFontOfSize:15];
self.contactNameTextField.keyboardType = UIKeyboardTypeEmailAddress;
[self.contactNameCell addSubview:self.contactNameTextField];
}
[self.contactNameTextField becomeFirstResponder];
}
if(indexPath.section == 1)
{
if(!self.contactEmailTextField)
{
self.contactEmailTextField = [[UITextField alloc] initWithFrame:CGRectMake(93, 14, 200, 20)];
self.contactEmailTextField.backgroundColor = [UIColor clearColor];
self.contactEmailTextField.font = [UIFont boldSystemFontOfSize:15];
self.contactEmailTextField.keyboardType = UIKeyboardTypeEmailAddress;
[self.contactEmailCell addSubview:self.contactNameTextField];
}
[self.contactEmailTextField becomeFirstResponder];
}
The code steps through as expected.
If I tap section 0 first, the name textfield becomes first responder. If I then tap section 1, the email textfield becomes first responder. If I then tap on section 0, even though becomeFirstResponder is called on the name textfield, it does not respond.
Also, if I tap section 1 first, even though becomeFirstResponder is called on the email textfield, it does not respond.
Please advise
Try calling resignFirstResponder of other textfield before calling becomeFirstResponder of it.
Replace
[self.contactNameTextField becomeFirstResponder];
with
[self.contactEmailTextField resignFirstResponder];
[self.contactNameTextField becomeFirstResponder];
Do same for section 1. Before calling resignFirstResponder check if textField in not nil.
Problem solved, silly cut and paste error with self.contactNameTextField in twice.

How to add multiple UITextfield in iOS 5?

How do I create and add multiple UITextField to my controller?
I can create one, like this:
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(5,5,100,25)];
tf.borderStyle = UITextBorderStyleRoundedRect;
[tf setReturnKeyType:UIReturnKeyDefault];
[tf setEnablesReturnKeyAutomatically:YES];
[tf setDelegate:self];
[self.view addSubview:tf]
But do I need to do that for each UITextField?
Whats the best approach to template UI Controls?
Put it in a loop, offset each text field's Y position and tag each text field:
for (int i = ; i < numberOfTextFieldsNeeded; i++) {
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(5, 5 + 35 * i ,100,25)]; // 10 px padding between each view
tf.tag = i + 1; // tag it for future reference (+1 because tag is 0 by default which might create problems)
tf.borderStyle = UITextBorderStyleRoundedRect;
[tf setReturnKeyType:UIReturnKeyDefault];
[tf setEnablesReturnKeyAutomatically:YES];
[tf setDelegate:self];
[self.view addSubview:tf]
// don't forget to do [tf release]; if not using ARC
}
Then in delegate methods perform actions based on tag of the textField that called each delegate method. For example to switch to next text view when user taps return key:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
UITextField *nextTextField = [self.view viewWithTag:textField.tag + 1];
[nextTextField becomeFirstResponder];
}
Keep in mind that sending messages to nil in Objective-C will not crash so it will be perfectly fine when user taps return key in last text field as UITextField *nextTextField = [self.view viewWithTag:textField.tag + 1]; will return nil, and calling becomeFirstResponder on nil will do nothing. But you can check if nextTextField is nil and do something else then, whatever you like.
You can use interface builder to create a view (bigger than the size that the screen fits) and programmatically add it to a scrollView.
This is in my opinion the best approach.

Resources