I have used two delegate methods to create a place holder for textView.
Code:
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
if([Description.text isEqualToString:#"Description of home"]&&[Description.font isEqual:[UIFont fontWithName:#"Helvetica" size:18]])
{
Description.text=nil;
}
if([Display.text isEqualToString:#"Display"]&&[Display.font isEqual:[UIFont fontWithName:#"Helvetica" size:18]])
{
Display.text=nil;
}
return YES;
}
-(BOOL)textViewShouldEndEditing:(UITextView *)textView
{
if ([Description.text isEqualToString:#""]) // Description is textViewObject
{
Description.text=#"Description of home";
Description.font=[UIFont fontWithName:#"Helvetica" size:18];
}
if ([Display.text isEqualToString:#""])
{
Display.text=#"Display"; // Display is textViewObject
Display.font=[UIFont fontWithName:#"Helvetica" size:18];
}
return YES;
}
#end
This is working correct. But problem is that when I am clicking on any textView, the text is getting nil from all textView. This is because I have connected all textView to delegate.
I want that text should disappear on particular textView only.
you could add conditions in the delegate methods like this :
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
if(textView == yourTextView1)
{
//your code for perticular textView1
}
else if(textView == yourTextView2)
{
//your code for perticular textView2
}
return YES;
}
You need to differentiate each of your UITextViews in some way.
If you are to have a small number of UITextViews on the screen, then you should save each of your UItextViews as a property. Check out this youtube video on creating IBOutlets
Then just name your UITextViews in order: textView1, textView2 etc...
Then in your delegate methods, you can check if the textView being passed in the method is equal to the property you want to delete text from.
if (textView == self.textView1) {
//delete text
} else {
//do nothing or something else
}
check if the delegate is operating on the wanted UITextView:
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
if(textView == Description && [Description.text isEqualToString:#"Description of home"]&&[Description.font isEqual:[UIFont fontWithName:#"Helvetica" size:18]])
{
Description.text=nil;
}
if(textView==Display && [Display.text isEqualToString:#"Display"]&&[Display.font isEqual:[UIFont fontWithName:#"Helvetica" size:18]])
{
Display.text=nil;
}
return YES;
}
Easiest solution by #
CmKndy for this problem is https://stackoverflow.com/a/10201671/3633534
use UITextViewDelegate delegate in your class and add text #"placeholder text here..." in your textView with lightGrayColor to display by default.
Following code is for place holder in textView :
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#"placeholder text here..."]) {
textView.text = #"";
textView.textColor = [UIColor blackColor]; //optional
}
[textView becomeFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#""]) {
textView.text = #"placeholder text here...";
textView.textColor = [UIColor lightGrayColor]; //optional
}
[textView resignFirstResponder];
}
For your question[Update]
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
if(textView == Description && [Description.text isEqualToString:#"Description of home"])
{
Description.text = #"";
}
else if(textView == Display && [Display.text isEqualToString:#"Display"])
{
Display.text = #"";
}
return YES;
}
-(BOOL)textViewShouldEndEditing:(UITextView *)textView
{
if (textView == Description && [Description.text isEqualToString:#""]) // Description is textViewObject
{
Description.text = #"Description of home";
Description.font=[UIFont fontWithName:#"Helvetica" size:18];
}
else if (textView == Display && [Display.text isEqualToString:#""])
{
Display.text = #"Display"; // Display is textViewObject
Display.font=[UIFont fontWithName:#"Helvetica" size:18];
}
return YES;
}
#end
Related
I know this may be perceived as a duplicate but I promise you it is not.
Everybody has given an answer similar to this:
if ([_confirm.text isEqualToString: _password.text] || resultantLength2 < 3) {
textField.textColor = [UIColor redColor];
[_next setEnabled:NO];
}else{
[_next setEnabled:YES];
}
}
So why does this not work?
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == _confirm || textField == _password) {
int resultantLength2 = textField.text.length + string.length - range.length;
NSLog(#"Length After Additions And Subtractions Will Be: %i letters", resultantLength2);
if ([_confirm.text isEqualToString: _password.text] || resultantLength2 < 3) {
textField.textColor = [UIColor redColor];
[_next setEnabled:NO];
}else{
[_next setEnabled:YES];
}
}
return YES;
}
Where I have a next button that gets dissabled
What we actually want to do is compare the strings in the text fields AFTER the text has changed, but currently, we're using a method that is fired BEFORE the text changes and asks whether or not the change is okay.
We can do some tricks in this method to get it work right, but why not just check the values after they've changed?
In the view controller's viewDidLoad, add these two lines:
[_confirm addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[_password addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
Now add the textFieldDidChange: method to compare the values in the textfield.
- (void)textFieldDidChange:(UITextField *)textField {
if (![_confirm.text isEqualToString: _password.text]) {
textField.textColor = [UIColor redColor];
[_next setEnabled:NO];
} else {
[_next setEnabled:YES];
}
}
Your problem is that you are in shouldChangeCharactersInRange, which is called before the text field is updated, but you are comparing the current value of _confirm.text
Also, your string comparison logic seems to be the wrong way around - you want NEXT enabled if the password is the same as the confirm I would think
I would try this -
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == _confirm) {
NSMutableString *newValue=[NSMutableString stringWithString:textField.text];
[newValue replaceCharactersInRange:range withString:string];
int resultantLength2 = newValue.length;
NSLog(#"Length After Additions And Subtractions Will Be: %i letters", resultantLength2);
if (([newValue isEqualToString: _password.text] == NO) || resultantLength2 < 3) {
textField.textColor = [UIColor redColor];
[_next setEnabled:NO];
}else{
textField.textColor = SOMETHING; // should reset text colour
[_next setEnabled:YES];
}
}
return YES;
}
I have a UIButton that is gray when the user enters a viewController. There is also a UITextView. If the user enters text into the UITextView, then the button should turn red, but if the text view is blank, the the button is gray. If was thinking of doing something like bellow, which does change the color to red if the user enters text, but if the user deletes the text, it stays red instead of going back to gray. Here is the code I am using:
- (void)textViewDidChange:(UITextView *)textView {
if (self.textView.text.length == 0) {
self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:193/255.5 green:193/255.0 blue:193/255.0 alpha:1.0];
}else{
self.navigationItem.rightBarButtonItem.tintColor = [UIColor redColor];
}
if (self.titleView.text.length == 0) {
self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:193/255.5 green:193/255.0 blue:193/255.0 alpha:1.0];
}else{
self.navigationItem.rightBarButtonItem.tintColor = [UIColor redColor];
}
NSLog(#"Typing has stopped");
}
Use if (self.textView.text.length == 0) instead of checking if the text is null.
For Swift 3:
if (self.textView.text.characters.count == 0)
You could bind the button image to the text view value and then use a value transformer to put in different colored images depending on if there's input.
Code is for OSX but hopefully it's adaptable.
#implementation DBHasTextImageTransformer
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
+ (Class)transformedValueClass
{
return [NSImage class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (id)transformedValue:(id)value
{
if ((value == NULL) || [value isEqualToString:#""]) {
return [NSImage imageNamed: #"NoTextImage"];
} else {
return [NSImage imageNamed: #"HasTextImage"];
}
}
#end
I have textField i want that when user enter data and presses space then it should add new row in tableView it works fine but i also want that on textFieldDidEndEditing it should also add row but when there is no space press by user right now in my code if any user pressed space code it add rows also and then other row for textFieldDidEndEditing.
-(void)textFieldDidEndEditing:(UITextField *)textField {
if (textField==tagTextField) {
[self showAnimationBack];
}
if (textField.tag==2) {
if (textField.text.length > 0 || ![tagTextField.text isEqualToString:#""]) {
[textField resignFirstResponder];
[tagArray addObject:tagInputField.text];
[tableView reloadData];
tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width, tableView.contentSize.height);
[tableView.layer setCornerRadius:7.0f];
[tableView.layer setMasksToBounds:YES];
tableView.layer.borderWidth = 0.5;
tableView.layer.borderColor = [UIColor grayColor].CGColor;
[self showAnimationBack];
float y = descriptionTextImageView.frame.origin.y;
float yp = publishButton.frame.origin.y;
NSLog(#"Y is %2.f",y);
if (y==405.00) {
[descriptionTextImageView setFrame:CGRectMake(48,y+30,250,90)];
[publishButton setFrame:CGRectMake(40,yp+30,250, 50)];
}
else{
y=y+30;
[descriptionTextImageView setFrame:CGRectMake(48,y,250,90)];
[publishButton setFrame:CGRectMake(40,yp+30,250, 50)];
}
}
}
}
And Other when space is pressed
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.tag==2) {
if ( [string isEqualToString:#" " ]){
if (textField.text.length > 0 || ![tagTextField.text isEqualToString:#""]) {
[textField resignFirstResponder];
[tagArray addObject:tagInputField.text];
[tableView reloadData];
tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width, tableView.contentSize.height);
[tableView.layer setCornerRadius:7.0f];
[tableView.layer setMasksToBounds:YES];
tableView.layer.borderWidth = 0.5;
tableView.layer.borderColor = [UIColor grayColor].CGColor;
float y = descriptionTextImageView.frame.origin.y;
float yp = publishButton.frame.origin.y;
NSLog(#"Y is %2.f",y);
if (y==405.00) {
[descriptionTextImageView setFrame:CGRectMake(48,y+30,250,90)];
[publishButton setFrame:CGRectMake(40,yp+30,250, 50)];
}
else{
y=y+30;
[descriptionTextImageView setFrame:CGRectMake(48,y,250,90)];
[publishButton setFrame:CGRectMake(40,yp+30,250, 50)];
}
[self showAnimationBack];
}
}
else {
return YES;
}
}
}
I could not completely get what are you actually looking for. If you are trying to avoid adding of new if user simply presses space bar without entering any other character then below piece of code can help you out:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string];
NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
if ([resultingString rangeOfCharacterFromSet:whitespaceSet].location == NSNotFound) {
return YES;
} else {
return NO;
}
}
use uitextview it's work's what you want
I tink u should call textFieldShouldReturn
textFieldDidEndEditing is fired when the textfield resigns it's first responder and textFieldShouldReturn is fired when the return button is pressed.
Mayb your textfield is never resigning its firstResponder. You can check it by putting some debug output or by navigating out of the textfield with a touch - eg start typing then just touch outside of the field to force it to resign firstResponder.
I have iphone app in which i am calling code one on textFieldShouldReturn and other on didEndEditing.
I want that when user return press the app should not called didEndEditing code and if user does not press return then call.
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField==tagTextField) {
[self showAnimationBack];
}
if (textField.tag==2 && [valueReturn isEqualToString:#"Yes"]) {
if (textField.text.length > 0 || ![tagTextField.text isEqualToString:#""]) {
[textField resignFirstResponder];
[tagArray addObject:tagInputField.text];
[tableView reloadData];
tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width, tableView.contentSize.height);
[tableView.layer setCornerRadius:7.0f];
[tableView.layer setMasksToBounds:YES];
tableView.layer.borderWidth = 0.5;
tableView.layer.borderColor = [UIColor grayColor].CGColor;
[self showAnimationBack];
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField.tag == 2)
{
if (textField.text.length > 0 || ![tagTextField.text isEqualToString:#""]) {
[textField resignFirstResponder];
[tagArray addObject:tagInputField.text];
[tableView reloadData];
tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width, tableView.contentSize.height);
[tableView.layer setCornerRadius:7.0f];
[tableView.layer setMasksToBounds:YES];
tableView.layer.borderWidth = 0.5;
tableView.layer.borderColor = [UIColor grayColor].CGColor;
[self showAnimationBack];
}
}
I call this also when user press return
- (void)keyboardDidHide:(NSNotification *)aNotification {
valueReturn=#"Yes";
}
Use isEditing value, as you (probably) resign the text view from first responder when the return key is pressed, textFieldDidEndEditing should have the text field at not-editing mode when it happens.
I am not sure if this a proper way of doing it but you can try this. Declare a variable isReturnPressed and make it YES in textFieldShouldReturn: and make it NO in textFieldDidEndEditing: . So you can check the condition as follows..
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if (isReturnedPressed == NO) {
// Do your stuff
}
else {
isReturnedPressed = NO
}
}
Hope this helps.
i have four textfields. User is allowed to enter only one digit in each text field.Once the user Enters single digit its focus should be on the next textfield. i have done this part and its working fine. Now, What i want is when i remove the text from the text field then its focus should move to previous textfield. i mean if i am deleting the text(digit) from the fourth text field then its focus should move to third text field. In short on removal of text the focus should be on previous textfield.
Now, what my problem is when i remove the text from the textfield then its focus moves to previous textfield but it clears the text of that textfield(the textfield on which i have set the focus).What i want is the text should not be removed on focus.
in .h file
IBOutlet UITextField *txtPinDigit1;
IBOutlet UITextField *txtPinDigit2;
IBOutlet UITextField *txtPinDigit3;
IBOutlet UITextField *txtPinDigit4;
UITextField *currentTextField;
in .m file
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField.tag==0)
{
currentTextField=txtPinDigit1;
}
else if(textField.tag==1)
{
currentTextField=txtPinDigit2;
}
else if(textField.tag==2)
{
currentTextField=txtPinDigit3;
if(isDelete)
{
textField.text=digit3;
}
}
else if(textField.tag==3)
{
currentTextField=txtPinDigit4;
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(([textField.text length]==1)&&(![string isEqualToString:#""]))
{
if(currentTextField==txtPinDigit1)
{
[txtPinDigit2 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit2)
{
[txtPinDigit3 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit3)
{
[txtPinDigit4 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit4)
{
textField.text = [textField.text substringToIndex:MAXLENGTH-1];
//[txtPinDigit4 resignFirstResponder];
//[txtPinDigit1 becomeFirstResponder];
}
}
else if([string isEqualToString:#""])
{
isDelete=YES;
NSLog(#"replacementString:%#",string);
// textField.text=string;
if(currentTextField==txtPinDigit4)
{
textField.text=string;
digit3=nil;
[digit3 release];
digit3=[[NSString alloc] initWithFormat:#"%i",[txtPinDigit3.text intValue]];
[txtPinDigit3 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit3)
{
textField.text=string;
[txtPinDigit2 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit2)
{
textField.text=string;
[txtPinDigit1 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit1)
{
textField.text=string;
// [txtPinDigit1 resignFirstResponder];
//[txtPinDigit1 becomeFirstResponder];
}
}
return YES;
}
in the above code MAXLENGTH=1 defined.
any help will be appreciated.
thanks in advance.
Try This code, Change shouldChangeCharactersInRange: Delegate Method
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] < 1)
{
if (textField.tag==2)
{
[txtPinDigit1 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
// txt2.text=#"";
}
else if (textField.tag==3)
{
[txtPinDigit2 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
}
else if (textField.tag==4)
{
[txtPinDigit3 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
}
return YES;
} else
{
// Otherwise we cut the length of newString to 1 (if needed) and set it to the textField.
textField.text = [newString length] > 1 ? [newString substringToIndex:1] : newString;
if (textField.tag==1)
{
[textField resignFirstResponder];
[txtPinDigit2 becomeFirstResponder];
}
else if (textField.tag==2)
{
[textField resignFirstResponder];
[txtPinDigit3 becomeFirstResponder];
}
else if (textField.tag==3)
{
[textField resignFirstResponder];
[txtPinDigit4 becomeFirstResponder];
}
return NO;
}
}
Check to check length via this way and put a break point at beginning of shouldChangeCharactersInRange
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int length = textField.text.length - range.length + string.length;
return YES;
}
I hope it will help you.
Before calling up to become first responder on filling up the 1st digit,bind the entered text inputs & the responder into dictionary...
On each previous/next condition,retrieve the information from the dictionary...The below example code is for the general previous/next custom actions(not auto though)..You just need to change the logic a bit based on the condition you prefer...
- (NSArray *) responders
{
if (_responders)
return _responders;
NSArray *textInputs = EditableTextInputsInView([[UIApplication sharedApplication] keyWindow]);
return [textInputs sortedArrayUsingComparator:^NSComparisonResult(UIView *textInput1, UIView *textInput2) {
UIView *commonAncestorView = textInput1.superview;
while (commonAncestorView && ![textInput2 isDescendantOfView:commonAncestorView])
commonAncestorView = commonAncestorView.superview;
CGRect frame1 = [textInput1 convertRect:textInput1.bounds toView:commonAncestorView];
CGRect frame2 = [textInput2 convertRect:textInput2.bounds toView:commonAncestorView];
return [#(CGRectGetMinY(frame1)) compare:#(CGRectGetMinY(frame2))];
}];
}
The below function should get called before doing previous/next auto tab.
- (Void) selectAdjacentResponder: (UISegmentedControl *) sender
{
NSArray *firstResponders = [self.responders filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIResponder *responder, NSDictionary *bindings) {
return [responder isFirstResponder];
}]];
NSLog(#"%#",firstResponders);
UIResponder *firstResponder = [firstResponders lastObject];
NSInteger offset = sender.selectedSegmentIndex == 0 ? -1 : +1;
NSInteger firstResponderIndex = [self.responders indexOfObject:firstResponder];
NSInteger adjacentResponderIndex = firstResponderIndex != NSNotFound ? firstResponderIndex + offset : NSNotFound;
UIResponder *adjacentResponder = nil;
if (adjacentResponderIndex >= 0 && adjacentResponderIndex < (NSInteger)[self.responders count])
adjacentResponder = [self.responders objectAtIndex:adjacentResponderIndex];
[adjacentResponder becomeFirstResponder];
}
Bit lengthier,but this is all i know a BIT :)..Happy coding...