Hide keyboard/ resignFirstResponder forcibly - iphone

i'm working on an app which has a tableView with a textField in the right side of its each cell(there are more than 20 cells).
i've created custom cell's for each row except for the last one.
In the last row there is only a button.
Now i want to call resignFirstResponder on the button's click.
What should i do Please help?

You will have to keep track of which textfield in which cell has the first responder and resign it like this.
[myCellTextField resignFirstResponder];

You probably want to keep track of the text field with the keyboard. Implement the <UITextFieldDelegate> protocol in your controller, and set the controller as each of the text fields' delegates. Write the textFieldDidBeginEditing: method like so, setting an instance variable called currentTextField:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
currentTextField = [textField retain];
}
Then, in your action for the button run [currentTextField resignFirstResponder].

Aopsfan's answer is probably the best solution so far. However, to add to it (as I cannot post comments), do remember to deallocate the object:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (currentTextField != nil) {
[currentTextField release];
}
currentTextField = [textField retain];
}
Better still use #property's and #synthesize so the runtime can do the memory management for you.
[ViewController].h
#property (nonatomic, retain) UITextField* currentTextField;
[ViewController].m
#synthesize currentTextField = _currentTextField;
- (void)viewDidLoad|Appear {
self.currentTextField = nil;
}
- (void) dealloc {
[_currentTextField release], _currentTextField = nil;
...
[super dealloc];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.currentTextField = textField;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.currentTextField) {
[self.currentTextField resignFirstResponder];
}
}

I think this link will help you:
Objective C: ResignFirstResponder with a button
Provide some code so that, it will be easier to help u.
Hope this helps you. :)

Related

textFieldShouldBeginEditing not being called

I am trying to use textFieldShouldBeginEditing to disable the keyboard from showing up for a custom UITextField. I'm implementing all the UITextFieldDelegate methods. However, for some reason, textFieldShouldBeginEditing actually never gets called.
The following delegate methods ALWAYS get called:
– textFieldDidBeginEditing:
– textFieldShouldEndEditing:
– textFieldDidEndEditing:
The view is structured in the following way:
UIViewController which holds a scrollview. Depending on the state of the view, this ScrollView will contain a UIView with a list of custom UITextFields.
I'm running iOS 4.3.5 (8L1) on this device.
Any ideas?
Edit; added some code snippets:
UIViewController has the following interface
#interface AViewController: UIViewController<UITextFieldDelegate>
Once the UIViewController loads, I connect all UITextFields to the view using
aSubView.aTextField.delegate = self;
(Simplified) delegate implementations located in AViewController
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return YES;
}
Custom UITextField code
Simplified implementation file --
#import "PVEntryTextField.h"
#import "EntryViewController.h"
#implementation PVEntryTextField
#synthesize isPasswordField, state, singleTap;
- (id)initWithCoder:(NSCoder *)inCoder
{
if (self = [super initWithCoder:inCoder])
{
self.font = [UIFont fontWithName:#"Helvetica-Bold" size:19];
self.textColor = [UIColor colorWithRed:51.0/255.0
green:51.0/255.0
blue:51.0/255.0
alpha:1.0];
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
}
return self;
}
- (CGRect)textRectForBounds:(CGRect)bounds
{
return CGRectMake(bounds.origin.x + 16, bounds.origin.y,
bounds.size.width - 16*2 - 10, bounds.size.height);
}
- (CGRect) editingRectForBounds:(CGRect)bounds
{
return [self textRectForBounds:bounds];
}
- (BOOL) canBecomeFirstResponder
{
return YES;
}
- (void) updateState:(int) newState
{
state = newState;
}
- (void)dealloc
{
[super dealloc];
}
#end
Is it posible that textFieldShouldBeginEditing is called by the default implementation of the method canBecomeFirstResponder?
Try implementing the method by [super canBecomeFirstResponder] or just removing it.
Have you set the UITextField delegate to "self"?
For anyone that comes here and didn't find a solution. My problem was that I created the textField in IB and then alloc one in my viewDidLoad. When I removed the instantiation, the delegate worked correctly as it was tied to the correct TF.
//I REMOVED these two lines because I created the textfield in IB
_nameTextField = [[UITextField alloc] init];
_priceTextField = [[UITextField alloc] init];
[_nameTextField setDelegate:self];
[_priceTextField setDelegate:self];
I also ran into the issue of not having textFieldShouldEndEditing or textFieldShouldReturn called. This occurred after updating my app's Storyboard.
The delegate methods were getting called when the UITextFields where part of the ViewController subclass.
But, when they were moved into a Scroll View within the ViewController, the methods were no longer called.
Setting their app delegates to self in ViewDidLoad fixed this problem.
self.emailField.delegate = self;
self.passwordField.delegate = self;
In Swift-3 following method required "_" before textField so that this delegate method will call. In my case it helps me.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
}
Dont know if is a typo error on copying the code here but the method name is incorrect:
CORRECT - textFieldShouldBeginEditing
YOURS - textFieldShoulBeginEditing (missing "d")

UITextField keyboard Issue

I have such a problem: I have a UITextField in my UITableViewCell. When I tap on that text field -> keyboard appears, but when I press Enter button keyboard don't disappear. I need such a behavior for my text field and keyboard:
When I pressed Enter, Esc - keyboard must disappear.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Where textField is UITextField in UITableViewCell
Implement textFieldShouldReturn: method in textField's delegate and call [textField resignFirstResponder] there - that will hide keyboard when return key is pressed.
I'm not sure if that will work for 'Esc' as well, but there's no such key on real device anyway so it must not be a problem
Try this
[txtField setReturnKeyType:UIReturnKeyDone];
txtField.enablesReturnKeyAutomatically=YES;
This may be an old post but I found it searching for the answer so chances are someone else might so don't shoot me for posting.
Just wanted to add
don't forget to make the delegate connection in IB for the UITextField
#interface Untitled2ViewController : UIViewController <UITextFieldDelegate>
{
IBOutlet UITextField *text;
}
#property (nonatomic, retain) IBOutlet UITextField *text;
#end
//m file
#import "Untitled2ViewController.h"
#implementation Untitled2ViewController
#synthesize text;
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
In xib file I set: Return Key: Done, Auto-anabling return key. I also tried without it, and still no reaction. Keyboard don't hides.
Write this code to create UITextLabel
UITextField *username = [[UITextField alloc]initWithFrame:CGRectMake(10.0f, 10.0f, 110.0f, 30.0f)]
[username setReturnKeyType:UIReturnKeyNext];
[username setDelegate:self];
[self.view addSubview:username];
Now to resign write this code.
-(void)resignKeyboard
{
if([username isEditing])
{
[username resignFirstResponder];
}
}
I hope it works for you.
try this
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
or this is for anywhere in the view
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}

UISearchBar and event fired when 'X' element is tapped

On the UISearchBar, there's an X element that allows you to clear all of the contents at once. Is there a way to get notified when this happens?
UISearchBarDelegate::searchBarCancelButtonClicked is fired only when the "Cancel" button is tapped.
The UISearchBar doesn't have a delegate method for this event. You can nearly get what you want by implementing the textDidChange: method of the callback delegate and checking for an empty string.
I don't recommend it, but there is another possible way. The UISearchBar is composed of a UITextField, which does have a delegate method that is called when the user taps the clear button (textFieldShouldClear:). You can get the UITextField by traversing the UISearchBar's child views:
(this is in the context of a derived UISearchBar class)
- (UIView*) textField
{
for (UIView* v in self.subviews)
{
if ( [v isKindOfClass: [UITextField class]] )
return v;
}
return nil;
}
from here, you could re-assign the UITextField delegate to your own implementation, taking care to forward delegate calls to the old delegate. This way you could intercept textFieldShouldClear:. Or if it turns out the UISearchBar is the delegate for the UITextField it contains you could swizzle the call to textFieldShouldClear:... Not ideal, clearly, but technically feasible.
I had the same issue and I solved this issue by using this function.
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
// This method has been called when u enter some text on search or Cancel the search.
if([searchText isEqualToString:#""] || searchText==nil) {
// Nothing to search, empty result.
[UIView animateWithDuration:0.2 animations:^ {
//Reposition search bar
[_searchBar setFrame:CGRectMake(230, 26, 43, 44)];
[_searchBar setNeedsLayout];
}];
}
}
Here is an answer from a previous question, this should do exactly what you want. UISearchbar clearButton forces the keyboard to appear
Here is "Method Swizzling" solution.
Create a new Category of UISearchBar. This category create a new method and swizzle method between -(BOOL)textFieldShouldClear:(UITextField *)textField; and -(BOOL)jbm_textFieldShouldClear:(UITextField *)textField in runtime.
Customize a new Protocol of UISearchBarDelegate in order to add a new method - (void)searchBarClearButtonClicked:(id)sender;
UISearchBar+JMBTextFieldControl.h
#protocol UISearchBarWithClearButtonDelegate <UISearchBarDelegate>
#optional
- (void)searchBarClearButtonClicked:(id)sender;
#end
#interface UISearchBar (JMBTextFieldControl)
#end
UISearchBar+JMBTextFieldControl.m
#import "UISearchBar+JMBTextFieldControl.h"
#import <objc/runtime.h>
#implementation NSObject (Swizzling)
+ (void)brc_swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
Method origMethod = class_getInstanceMethod(self, origSelector);
Method newMethod = class_getInstanceMethod(self, newSelector);
if(class_addMethod(self, origSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(self, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
}
#end
#implementation UISearchBar (JMBTextFieldControl)
+ (void)load {
[self brc_swizzleMethod:#selector(textFieldShouldClear:) withMethod:#selector(jbm_textFieldShouldClear:)];
}
- (id<UISearchBarWithClearButtonDelegate>)jbm_customDelegate {
if( [[self delegate] conformsToProtocol:#protocol(UISearchBarWithClearButtonDelegate)] )
return (id<UISearchBarWithClearButtonDelegate>)[self delegate];
else
return nil;
}
- (BOOL)jbm_textFieldShouldClear:(UITextField *)textField
{
if ( [[self jbm_customDelegate] respondsToSelector:#selector(searchBarClearButtonClicked:)] )
[[self jbm_customDelegate] searchBarClearButtonClicked:self];
return [self jbm_textFieldShouldClear:textField];
}
#end
Reference
Dave DeLong -
How to add a method to an existing protocol in Cocoa?
Nikolay Vlasov - CCBottomRefreshControl

Best way to use "Next" version of Return button on UITextField to move to next UITextField

I use the "Next" value for the "Return Key" to get the Next button in place of the Done button, but (obviously) pressing it doesn't automatically move to the next UITextField in my view.
What's the right way to do this? On a larger topic, what are some tips for properly building forms in the iPhone SDK?
Make some object the first text field's delegate, and implement the - (BOOL)textFieldShouldReturn:(UITextField *)textField method; in that, call the second text field's -becomeFirstResponder. Returning YES from that will make the text field perform its default behavior for the return button – I think that's generally sending its action message. If you don't have anything added as a target of that action, it doesn't really matter what you return.
To build on Noah's answer, if you have a lot of textfields and don't feel like having a bunch of if's, you could do it this way:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
UIView *view = [self.view viewWithTag:textField.tag + 1];
if (!view)
[textField resignFirstResponder];
else
[view becomeFirstResponder];
return YES;
}
Once you tag every textfield starting at any number, as long as they're tagged sequentially, in storyboard or in code, it should work.
For Swift:
func textFieldShouldReturn(textField: UITextField) -> Bool {
//your collection of textfields
guard let i = textFields.indexOf(textField) else { return false }
if i + 1 < textFields.count {
textFields[i + 1].becomeFirstResponder()
return true
}
textField.resignFirstResponder()
return true
}
This seems to work quite well and doesn't require the tag system many are suggesting. There are 2 things to note with this solution though:
All the UITextFields must be in the same UIView (have the same superview).
The UITextFields need to be in the right order in the interface builder.
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
/*
* 1. Loop through the textfield's superview
* 2. Get the next textfield in the superview
* 3. Focus that textfield
*/
UIView *superView = [textField superview];
BOOL foundCurrent = false;
for (UITextField *tf in superView.subviews) {
// Set focus on the next textfield
if (foundCurrent) {
[tf becomeFirstResponder];
return NO;
}
//Find current textfield
if ([tf isEqual:textField]) {
foundCurrent = true;
}
}
return YES;
}
I don't like to deal with tag so here is my solution. Create an IBOutletCollection of all your textFields in your ViewController, drag to connect your textFields in order from top to bottom.
#interface ViewController () <UITextFieldDelegate>
#property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *allTextFields;
#end
In viewDidLoad set your textFields delegate. (Or set it in storyboard).
for (VVTextField *tf in self.allTextFields) {
tf.delegate = self;
}
Then implement UITextField Delegate
#pragma mark - UITextField Delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSUInteger currentIndex = [self.allTextFields indexOfObject:textField];
NSUInteger nextIndex = currentIndex+1;
if (nextIndex < self.allTextFields.count) {
[[self.allTextFields objectAtIndex:nextIndex] becomeFirstResponder];
} else {
[[self.allTextFields objectAtIndex:currentIndex] resignFirstResponder];
}
return YES;
}
I've been struggling with this issue too...and as a result I've created small library for handling multiple textfields. You can find it on github GNKeyboardAwareScrollView#GNTextFieldsManager.
You can initialise it with array of textfields:
NSArray *myTextFields = #[...]; // the order of array matters!
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithTextFields:myTextFields];
Or by specifying parent view (and setting tags for all views):
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithView:self.view];
Hope i'll be useful for somebody :)

Keyboard Iphone

Is possible to know when the user touch the keyboard iphone? When the user touch some button from keyboard... :/
The easiest way is to use a TextField. Even is your UI Does not call for one, you can set it's frame to zero so it doesnt show up onscreen. Then you can get access to the keys pressed by using the text field's delegate callback methods.
- (void)viewDidLoad {
[super viewDidLoad];
//CGRectZero because we don't want the textfield to be shown onscreen
UITextField *f = [[UITextField alloc] initWithFrame:CGRectZero];
//We set the delegate so we can grab keypressed
f.delegate = self;
[self.view addSubview:f];
[f becomeFirstResponder]; //Show the keyboard
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
if (string.length >0) {
NSLog(#"%# Pressed",string);
}
else {
NSLog(#"Backspcae pressed");
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(#"return pressed");
return YES;
}
Note: to avoid a compiler warning, make sure in your .h file the class explicitly says it implements the UITextFieldDelegate protocal. ie:
#interface MyViewController : UIViewController <UITextFieldDelegate>