which event to use for readonly textfield when text is changed - ios

I have a readonly text field. I want that when the value is changed to this field , to set another text field also.
Which event should I use. tried with editingChanged , but it's not getting called.
pls help.

If the text field is readonly, then you must set the text programmatically, right? In that case, when you set the text, set the text of the other text field at the same time.
If I misunderstood your question, and the user edits the textfield, you can listen for changes this way:
[textField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventValueChanged];
And handle the callback the following way:
- (void)textFieldDidChange:(UITextField *)textField
{
// Handle change
}

From Apple documentation
textFieldShouldBeginEditing: Asks the delegate if editing should begin
in the specified text field.
(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
Parameters textField - The text field for which editing is about to
begin.
Return Value YES if an editing session should be initiated; otherwise,
NO to disallow editing.
Discussion When the user performs an action that would normally
initiate an editing session, the text field calls this method first to
see if editing should actually proceed. In most circumstances, you
would simply return YES from this method to allow editing to proceed.
Implementation of this method by the delegate is optional. If it is
not present, editing proceeds as if this method had returned YES.
So use something like:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
BOOL editable;
if (textField == myReadOnlyTextField) {
editable = NO;
} else if (textField == myEditableTextField) {
editable = YES;
} else {
// editable = YES/NO/Other Logic
}
return editable;
}
Also in order for the delegate methods to get called your interface should conform to the UITextfieldProtocol: add this to your .h file <UITextFieldDelegate> so it looks like this:
#interface ViewController : UIViewController <UITextFieldDelegate>

Implement this delegate method if you are implementing in ios.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange{}
If you are implementing in macos then use below delegate method:-
-(void)controlTextDidChange

Related

Execute code in objective-c when enter key is pressed?

I'm working on an Objective-C Xcode project in Xcode 6. I have a textfield and a button that checks what's in the textfield when pressed.
However, I would like the code to run when enter key is pressed instead of the submit button.
I have seen that you can set the key equivalent for a button in Xcode however this option doesn't appear to feature in Xcode 6.
Implement textField delegate method.
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self callYourCodeWantToExecute];
//return YES; // want to hide keyboard
//return NO; // want keyboard
}
You need to:
Set delegate for textField
In your delegate object handle -(BOOL)textFieldShouldReturn:(UITextField *)textField i.e. do what you need to do when return pressed and return YES if you want to text field get return NO if you don't want to handle return for text field.
First make your file delegate for UITextField and then add this method to your code ..
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Follow the below steps.
Set delegate of UITExtfield
Add tag value if there are multiple textfield
Now call the delegate method of UITextfield same as below.
Swift
optional func textFieldShouldReturn(_ textField: UITextField) -> Bool
Hope this helps!

Clear the content of the UITextField's text property for tap

I have a UITextField called place, it's text property contains an NSString. I would like to clear the existing content from the text property when the user taps into the text field.
I tried the code above, but nothing happened. I also tried it with the placeholder property, but it was the same. Do you have any idea what could be the problem? I think it should work.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.place.text = nil;
}
2, version - in this case nothing appears in the text field from the beginning
- (void)viewDidLoad
{
[super viewDidLoad];
...
[self textFieldDidBeginEditing:place];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
textField.text = nil;
}
There is a property clearsOnBeginEditing you can set to YES programmatically or there is a checkbox in Interface Builder.
If you also want to clear your placeholder
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
textField.placeholder = nil;
}
Double check that the UITextField self.place has it's delegate set to your view controller and validate that textFieldDidBeginEditing is being called.

How to disable keyboard appearing when hitting on a text field , iOS?

I have a text field , and i need when the user presses it to show a custom picker.
The picker is shown fine , but the problem is that the keyboard appears on the bottom and i dont want that.
This is an iPad project which i am trying to convert from my iphone one. On the iPhone , this works well and the keyboard is always hidden.
What could i be missing/forgetting to do here ?
EDIT
For future reference what actually happened here , was that in fact both times (iphone & ipad) the keyboard was not hidden. I just thought that it was hidden in the iphone because my picker , which was popping from the bottom was hiding the keyboard as it was on top of it. But on ipad this wasnt the case.
Anyway i fixed it , using the delegate method suggested below.
Caution , i accepted this answer cause it was the one answering specifically what i wanted. The rest of the answers are correct and my considered better for other implementations.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Here You can do additional code or task instead of writing with keyboard
return NO;
}
this delegate method will get called first when you hit to textfield and if you write NO as a boolean value means you dont want to begin editing so it will not present Keyboard.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textfield == yourtextField)
{
[textfield resignFirstResponder];
// Show you custom picker here....
return NO;
}
}
and you need to implement the uitextfielddelegate in the controller.
and give assign the delegate to yourtextField.
Use textfield delegate.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
It looks like all of these answers take one approach, to simply deny the keyboard before it comes up. This prevents first responder status, which has many advantages.
One simple approach that allows you to maintain first responder status is to create an empty view and assign that to the inputView property on your input field. If you are using iOS 9 (or later?) you will also have to get rid of the inputAssistantItem objects as well.
UITextField *field = [[UITextField alloc] init];
field.inputView = self.emptyKeyboard.view;
UITextInputAssistantItem *aItem = [field inputAssistantItem];
aItem.leadingBarButtonGroups = #[];
aItem.trailingBarButtonGroups = #[];
Then if you want to control the field from an alternate view controller, you can do so by adding targets:
[field addTarget:self.numberPad action:#selector(editingBegan:) forControlEvents:UIControlEventEditingDidBegin];
[field addTarget:self.numberPad action:#selector(editingEnded:) forControlEvents:UIControlEventEditingDidEnd];
[field addTarget:self.numberPad action:#selector(fieldChanged:) forControlEvents:UIControlEventEditingChanged];
It is also possible to do this a lot more cleanly by subclassing UITextField.
Use the textField Delegate,
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
textField=nil;
return NO;
}
swift 3.0 version
First set the delegate for the text field
self.textfield.delegate = self
Then in an extension
extension ViewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Here you can do for Specific text Field by
if (textField==(the text field you don't want to show keyboard)) {
NSLog(#"don't show keyboard");
return NO;
}
else {
return YES;
}
}
Swift 3/4
Add:- UITextFieldDelegate in your class.
Add:- self.textField.delegate = self In ViewDidLoad
last one just add this func -
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}

clearing a UITextField when the user starts typing

short version: How can I make a UITextField box remove all content on the users first keypress? I don't want the info removed until the user starts typing something. ie, clearing it on begin edit is not good enough.
long version: I have three UITextField that loop around (using the return key and catching the press in the "shouldReturn" method. There is text already in the UITextField, and if the user doesn't type anything and just goes to the next UITextField, the value should stay (default behaviour).
But I want it that if the user starts typing, it automatically clears the text first. Something like having the whole field highlighted, and then typing anything deletes the fiels and then adds the user keypress.
"Clear when editing begins" is no good, because the text is immediately cleared on the cursor appearing in the field. That's not desired. I thought I could use the placeholder here, but that doesn't work as a default, and I can't find a default value property. The Highlighted and Selected properties don't do anything in this regard either.
There is a delegate method called
textFieldDidBeginEditing:(UITextField*) tf{
tf.startedEdinting = YES;
}
textFeildDidEndEditing: (UITextField*) tf {
tf.startedEditing = NO;
}
Add startEditing in a category to UITextField.
Then if value changes clear the field:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.startEditing){
textField.text = string;
} else {
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
}
}
You can add the property to the UITextField category in the following way:
.h
#property (nonatomic, assign) BOOL startEditing;
.m
#dynamic startEditing;
- (void) setStartEditing:(BOOL)startEditing_in{
NSNumber* num = [NSNumber numberWithBool:startEditing_in];
objc_setAssociatedObject(self, myConstant, num, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL) startEditing{
NSNumber* num = objc_getAssociatedObject(self, myConstant);
return [num boolValue];
}
Declare a BOOL variable in your .h file like.
BOOL clearField;
And implement the delegate methods like:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
clearField = YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
clearField = NO;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
clearField = NO;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(clearField)
{
textField.text = #""
clearField = NO;
}
}
I want to thank people for their answers, I implemented both of the main methods described here and both worked flawlessly. But I have since come across a much simpler, nicer answer and involves only one line of code :)
In the textField's didBeginEditing method, place [self.textField selectAll:self]; or [self.textField selectAll:nil];
The original answer I found had selectAll:self but this shows the cut/copy/paste menu. If you send nil instead of self the menu doesn't appear.
Adding this one line of code highlights the text on entering the textField (so gives the user a visual cue), and only removes everything once a key is pressed.
Another solution that fulfils the same purpose is by simply using a text field placeholder which is defined as:
The string that is displayed when there is no other text in the text field.
So as soon as the user starts typing, the placeholder text disappears.
That's something you can set from the storyboard, or programmatically. (Yes it took me two hours trying to figure it the harder way.. when the solution was literally one line change of code).
If you want to clear the text one the user interacts with it, there is an option in interface builder to where you can set the text field to "Clear when editing begins."
Try to use the following method.
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {
if(isFirsttime==YES)
{
textfield.text==#"";
isFirsttime=NO;
}
return YES;
}
Declare and initialize a NSString variable for your textField's initial text
NSString *initialText=#"initial text";
Then implement methods:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
if(textField.text isEqualToString:initialText)
{
textField.text=#"";
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if(textField.text isEqualToString:#"")
{
textField.text=initialText;
}
}

Capture text from UITextField in instance variable when another UIButton is pressed on UIView

I have a few UITextFields (within UITableViewCells) on my UIView with a "Save" UIButton. I want to do some basic validation on the UITextFields when the user clicks the "Save" button.
I have overridden textFieldDidEndEditing to save each of my UITextField data to an instance variable; however, if a user clicks the save button before either clicking the "Return" button of the UIKeyboard or clicking on another UITextField the data in my last UITextField is never saved to my instance variable and validation always fails.
I am looking for a way to trigger an "onBlur" (I know that's a JS thing)-type event to save my string in UITextField to my instance variable.
I've looked through the UITextFieldDelegate Protocol and I do not see anything like this.
Is there a method I may be missing?
to trigger textFieldDidEndEditing on your UITextField, you will need to call
[_txt resignFirstResponder];
were _txt is your UITextField
Please note that if you dont have a reference to _txt and you need to find the first responder in order to resign it
You could use the solution from this question Get the current first responder without using a private API
Then instead of calling
[_txt resignFirstResponder];
you would call
[self.view findAndResignFirstResponder];
Try this
// if we encounter a newline character return
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// enter closes the keyboard
if ([string isEqualToString:#"\n"])
{
[textField resignFirstResponder];
return NO;
}
return YES;
}
which will trigger
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
// Call webservice
return YES;
}

Resources