I set UITextFieldDelegate in my .h and in my .m have #property (strong, nonatomic) IBOutlet UITextField *myPhoneNumber;
In my viewDidLoad method I have
[self.myPhoneNumber setDelegate:self];
[self.myPhoneNumber addTarget:self
action:#selector(editingChanged:)
forControlEvents:UIControlEventEditingChanged];
My editingChanged: method listens to make sure the text input is >9 characters and then enables a button
- (IBAction)editingChanged:(id)sender {
if ([self.myPhoneNumber.text length] <= 9) {
self.myButton.enabled = NO;
}
else {
self.myButton.enabled = YES;
}
}
This works exactly how I want it to but when I press return on the keyboard to hide it this crashes the app with the error:
2014-07-15 08:08:27.089 sample-chat[47702:90b] -[MyViewController editingChanged]: unrecognized selector sent to instance 0x10ba7420
2014-07-15 08:08:27.093 sample-chat[47702:90b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyViewController editingChanged]: unrecognized selector sent to instance 0x10ba7420'
My method for returning the keyboard is as follows
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
You specified the return type of editingChanged: as IBAction. This is only required for linking up this method in Interface Builder, which would be redundant since you manually added the UIControlEventEditingChanged listener in viewDidLoad.
Either use
- (void)editingChanged:(id)sender
OR
use the method as is, but link it to the UIControlEventEditingChanged in Interface Builder.
Try this Way #mostly
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger length = editingTextField.text.length - range.length + string.length;
if (length > 0) {
yourButton.enabled = YES;
} else {
yourButton.enabled = NO;
}
return YES;
}
oky u can also try do this by using NSNotificationCenter, for example u want t check each character that entered to text field then u can try this
for example
//add the observer
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(editingChanged:) name:UITextFieldTextDidChangeNotification object:nil];
}
//remove the observer
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
}
- (void)editingChanged:(id)sender
{
if ([self.myPhoneNumber.text length] <= 9) {
self.myButton.enabled = NO;
}
else {
self.myButton.enabled = YES;
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
I think there is no need to use a custom selector like you done. It is better to use the text field delegate methods to manage this.
Set the delegate [self.myPhoneNumber setDelegate:self];
And implement the delegate methods like :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
self.myButton.enabled = NO;
if (textField == _myPhoneNumber)
{
if (textField.text.length > 9)
{
self.myButton.enabled = YES;
}
}
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[self.view endEditing:YES];
return YES;
}
Related
coding environment sierra 10.12,Xcode 8.1. Two textField in my roorView, if first textfield's text is nil, second textfield will can't be editing.When i used resignFirstResponder method to turn off keyboard in textFieldDidBeginEditing: method, keyboard not disappear. I add a fullscreen TapGesture in rootView. I'm very confused,anyone have ideas to help me deal with this problem?
`
#pragma mark -- UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if (textField == self.password) {
[self.username resignFirstResponder];
NSString *name = self.username.text;
if ([name isEqualToString:#""]) {
[CFBlurHUD showFaild:#"sign in error!"];
[self performSelector:#selector(dismmiss) withObject:nil afterDelay:1.5f];
self.password.enabled = NO;
}
}
}
- (void)dismmiss{
[CFBlurHUD dismiss];
self.password.enabled = YES;
}
`
If you want to simply dismiss a keyboard from view, try the following:
self.view.endEditing = true;
use your UITextFieldDelegate methods specifically UITextFieldShouldBeginEditing and return NO and execute the code to show the popover instead. This way the keyboard is never shown to begin with
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self.view endEditing:YES];
return NO;
}
Because current textfiled is password: if (textField == self.password) {. But you set:
[self.username resignFirstResponder];
It 's not correct.
Try:
[self.username resignFirstResponder];
[self.password resignFirstResponder];
or :
self.view.endEditting = true;
use your UITextFieldDelegate methods specifically UITextFieldShouldBeginEditing and return NO and execute the code to show the popover instead. This way the keyboard is never shown to begin with
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self.view endEditing:YES];
return NO;
}
First step for dismiss keyboard Give textfeild delegate in storyboard
Or Also give by code :
self.txtName.delegate = self;
Dismiss keyboard when tap gesture method called:
- (void)dismmiss{
[self.view endEditing:YES];
[CFBlurHUD dismiss];
self.password.enabled = YES;
}
or Also Dismiss when touch anywhere in View:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
Or when user press return button in keyboard:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
I have an OpenGL ES app which uses keyboard. I can make the keyboard pop-up on screen when screen is touched. If I am correct, each time I press a key,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
should be called. But it doesn't. The app was initially a pure OpenGL Mac game, which I am trying to make an iOS version of, so I am not using storyboard. I prefer to do everything programmatically if possible. Here is my code for ViewController.h:
#import <GLKit/GLKit.h>
#import "KeyboardView.h"
#interface ViewController : GLKViewController {
KeyboardView* keyBoard;
}
#end
relevant parts of ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
CGRect viewRect = CGRectMake(0, 0, 100, 100);
keyBoard = [[KeyboardView alloc] initWithFrame:viewRect];
[self setupGL];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view addSubview:keyBoard];
[keyBoard becomeFirstResponder];
}
KeyboardView.h:
#import <UIKit/UIKit.h>
#interface KeyboardView : UIView <UIKeyInput, UITextFieldDelegate> {
UITextField *field;
}
KeyboardView.m:
#import "KeyboardView.h"
#implementation KeyboardView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
field = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 10)];
}
return self;
}
- (void)insertText:(NSString *)text {
}
- (void)deleteBackward {
}
- (BOOL)hasText {
return YES;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSLog(#"text: %#", textField.text);
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] < 1) {
return YES;
} else
{
textField.text = [newString length] > 1 ? [newString substringToIndex:1] : newString;
[textField resignFirstResponder];
return NO;
}
}
#end
I need to be able to get each character entered by user while keyboard is active. I most confess, I am a little bit confused. I am not sure if my approach is correct, so I really appreciate your help.
The keyboard text input isn't captured through the UITextField's
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
It is indeed captured through UIKeyInput's
- (void)insertText:(NSString *)text;
I am using the soft keyboard to capture text on my GLKView (OpenGLES) app, and I don't even need any UITextField at all
For reference:
UIKeyInput Reference Doc
EDIT:
You need to call your keyboardview's becomeFirstResponder to show your keyboard and call resignFirstResponder to hide it
You also need to override canBecomeFirstResponder and return TRUE
I am facing the the wierdest bug (ether in my app or in IOS 7.1) ever.
After many hours I managed to create a simple app that demonstrate the problem.
Two UITextField - Dragged and dropped from interface builder and wired to t1, t2.
the ViewController:
#implementation ViewController
#synthesize t1;
#synthesize t2;
#pragma mark - UITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)iTextField {
NSLog(#"textFieldDidBeginEditing");
[iTextField performSelector:#selector(selectAll:) withObject:iTextField afterDelay:0.0];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
t1.delegate = self;
t2.delegate = self;
}
#end
When tapping on t1 and t2 at the same time, both textFields become first responder in an endless loop!
When omitting ether the PerformSelector statement or the textField:shouldChangeCharactersInRange: implementation, problem is gone.
Can someone explain why does it happen?
Edit: Also set the exclusiveTouch property of each UITextField to: YES to prevent them from editing at the same time.
- (void)viewDidLoad
{
[super viewDidLoad];
t1.exclusiveTouch = YES;
t2.exclusiveTouch = YES;
t1.delegate = self;
t2.delegate = self;
}
- (void)textFieldDidBeginEditing:(UITextField *)iTextField
{
[iTextField performSelector:#selector(selectAll:) withObject:nil afterDelay:0.0];
}
Or more simply without using the exclusiveTouch properties:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)iTextField
{
if (iTextField == t1 && t2.isFirstResponder == NO)
{
return YES;
}
else if (iTextField == t2 && t1.isFirstResponder == NO)
{
return YES;
}
return NO;
}
I try to use the selectedTextRange property to instead of selectAll, it makes the endless loop's problem gone.
func textFieldDidBeginEditing(_ textField: UITextField) {
DispatchQueue.main.async {
let begin = textField.beginningOfDocument
let end = textField.endOfDocument
textField.selectedTextRange = textField.textRange(from: begin, to: end)
}
}
I want to hide the View after clear the Text field data.But My view is not hiding.Please give me the solution i am using this code
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
partialSearchView.hidden = YES;
isCheckType = YES;
return YES;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
partialSearchView.hidden = NO;
isCheckType = NO;
return YES;
}
you should use the setter method: ...
[self.partialSearchView setHidden:YES];
- (BOOL)textFieldShouldClear:(UITextField *)textField
The text field calls this method in response to the user pressing the built-in clear button. (This button is not shown by default but can be enabled by changing the value in the clearButtonMode property of the text field.) This method is also called when editing begins and the clearsOnBeginEditing property of the text field is set to YES.
Implementation of this method by the delegate is optional. If it is not present, the text is cleared as if this method had returned YES.
you need actually implementation
- (BOOL)textFieldShouldClear:(UITextField *)textField {
partialSearchView.hidden = YES;
isCheckType = YES;
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (isCheckType )
return YES;
partialSearchView.hidden = NO;
isCheckType = NO;
if (textField.text.length >=8) {
return NO; // return NO to not change text
} else {
return YES;
}
}
I have in my TableViewCell 2 TextFields.
For the 2nd TextField i need a confirm to enable a button.
I´m using this code to determine if the confirm button should be enabled, but it doesn't work:
-(BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
textField = self.installDeviceCell.passWordTextFieldOutlet;
[textField addTarget:selfaction:#selector(checkTextField:)forControlEvents:UIControlEventEditingChanged];
return YES;
}
-(void)checkTextField:(id)sender
{
UITextField* textField = (UITextField*)sender;
if ([textField.text length] < 7) {
self.installDeviceCell.installDeviceTouchUpInsideButton.enabled = NO;
}else if ([textField.text length] > 7){
self.installDeviceCell.installDeviceTouchUpInsideButton.enabled = YES;
}else{
self.installDeviceCell.installDeviceTouchUpInsideButton.enabled = YES;
}
}
Have you assigned your UITextFieldDelegate for your UITextField when it is being instatiated? If don't assign the it the delegate methods for the UITextField will not be called.
Also make sure that in the header file of the delegate you specify the delegate of the interface e.g.
#interface MyDelegate <UITextFieldDelegate>
// ...
#end
Finally you're doing your text calculations a little oddly. You can do all your computations witin shouldChangeCharactersInRange. You also don't need to add the target or overwrite the textField property. Simply check if the replacementString is greater than 7 characters. Your final code might look something like this:
-(BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string length] < 7) {
self.installDeviceCell.installDeviceTouchUpInsideButton.enabled = NO;
} else {
self.installDeviceCell.installDeviceTouchUpInsideButton.enabled = YES;
}
return YES;
}
See this great answer on delegation for more info: https://stackoverflow.com/a/626946/740474