I have problem with hide keyboard when I showed optionsSheet.
Where is the problem in my code?
- (void)optionsSheet2{
if(optionsSheet2) {
[optionsSheet2 dismissWithClickedButtonIndex:-1 animated:YES];
optionsSheet2 = nil;
}
optionsSheet2 = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(#"Cancel", nil) destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(#"Delete", nil), NSLocalizedString(#"Delete all", nil), nil];
[optionsSheet2 showInView:self.parentViewController.view];
}
- (void)dismissKeyboard {
[_uiSearchBar resignFirstResponder];
[_uiSearchBar setShowsCancelButton:NO animated:YES];
[_uiSearchBar setHidden:true];
[self.view endEditing:YES];
}
you change code like this:
- (void)optionsSheet2
{
[self.view endEditing:YES];
}
Use this simple Solution
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Works with UITextField, UITextView and all subviews.
Related
I have searched the entire internet and tried different ways to implement UITextFieldShouldReturn, but when I run it in the simulator it just doesn't work.
What I'm trying to do is move from the first textfield(emailTextField) to the second one( nameTextField ) when user clicks next button on the keyboard. The same for the second textfield's keyboard and dismiss the keyboard when user clicks done button on the last textfield( numberTextField ).
Here is my code, can anyone help me with this?
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.emailTextField.placeholder = #"Your Pitt Email(optional)";
self.nameTextField.placeholder = #"Lost ID Name";
self.numberTextField.placeholder = #"Lost ID Series Number(optional)";
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//release delegate
-(void)dealloc{
self.emailTextField.delegate = nil;
self.nameTextField.delegate = nil;
self.numberTextField.delegate = nil;
}
//dismiss keyboard when it's called
-(void)dismissKeyboard{
[self.emailTextField resignFirstResponder];
[self.nameTextField resignFirstResponder];
[self.numberTextField resignFirstResponder];
}
//when a textfield begins editing, this will happen
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"";
}else if(textField == self.nameTextField){
textField.placeholder = #"";
}else{
textField.placeholder = #"";
}
}
//when a textfield ends editing, this will happen
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"Your Pitt Email(optional)";
[self textFieldShouldReturn:self.emailTextField];
}else if(textField == self.nameTextField){
textField.placeholder = #"Lost ID Name";
[self textFieldShouldReturn:self.nameTextField];
}else{
textField.placeholder = #"Lost ID Series Number(Optional)";
[self textFieldShouldReturn:self.numberTextField];
}
}
//return button set up
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
//when confirm is pressed
- (IBAction)confirmButton:(id)sender {
[self dismissKeyboard];
}
#end`
Change
[self.emailTextField.delegate self];
to
self.emailTextField.delegate = self;
Also remove those delegates from dealloc. You can put them from viewDidDisappear
Try this code snippet. Here i am taking only two
UITextFields.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField==_txtEmail)
{
[_txtEmail resignFirstResponder];
[_txtPassword becomeFirstResponder];
}
else if (textField==_txtPassword)
{
[_txtPassword resignFirstResponder];
}
return YES;
}
This function is enough to return keyboard from text fields.
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Your these 3 lines are not working.
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
If you are using storyboard, connect delegates of the text fields with the view.
You can use this code.It is working for me..
-(void)tool{
UIToolbar *toolbar = [[UIToolbar alloc] init];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];
UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(resignKeyboard)];
[doneButton setTintColor:[UIColor whiteColor]];
UIBarButtonItem *Next = [[UIBarButtonItem alloc]initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector(Nextbutton)];
[Next setTintColor:[UIColor whiteColor]];
NSArray *itemsArray = [NSArray arrayWithObjects:Next,flexButton,doneButton,nil];
[toolbar setItems:itemsArray];
[FirstNameTextField setInputAccessoryView:toolbar];
[LastNameTextfield setInputAccessoryView:toolbar];
[EmailAddressTextField setInputAccessoryView:toolbar];
[PasswordTextfield setInputAccessoryView:toolbar];
[ConfirmPasswordTextfield setInputAccessoryView:toolbar];}
-(void)Nextbutton{
if ([FirstNameTextField isFirstResponder])
{
[LastNameTextfield becomeFirstResponder];
}
else if ([LastNameTextfield isFirstResponder])
{
[EmailAddressTextField becomeFirstResponder];
}
else if ([EmailAddressTextField isFirstResponder])
{
[PasswordTextfield becomeFirstResponder];
}
else if ([PasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield becomeFirstResponder];
}
else if ([ConfirmPasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield resignFirstResponder];
}}
-(void)resignKeyboard{
[FirstNameTextField resignFirstResponder];
[EmailAddressTextField resignFirstResponder];
[LastNameTextfield resignFirstResponder];
[PasswordTextfield resignFirstResponder];
[ConfirmPasswordTextfield resignFirstResponder];}
First of all you need to set the delegate right. Then You need to give your next textfield the becomeNextResponder call which should be ideally done in the shouldReturn delegate method.
In your viewDidLoad method, paste this.
self.emailTextField.tag = 2000;
self.nameTextField.tag = 3000;
self.numberTextField.tag = 4000;
Now edit your textFieldShouldReturn method like this:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
if(textfield.tag<4000)
{
UITextField *nextTextField = (UITextField *)[self.view viewWithTag:textField.tag+1000];
[nextTextField becomeFirstResponder];
}
return YES;
}
you can always use a library to accomplish what you need to do !!
use this library : tpAvoidKeyboard
Read how to use it and there you go all the next buttons and clicks outside text fields to dismiss the keyboard and the the done button on the last textfield to dismiss the keyboard, all those features are already implemented
I want to hide the keyboard by touching the view. Everybody recommends to use this method, saying there's no need to link or anything else, but is not working.
The problem is that my method is not called.Is there anything else that should be done?
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
I had trouble with this so use a method that loops through all views seeing if they are textviews and firstResponders. Not sure of the structure of a UITextView but you might need to check for that too although it may be covered.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView *txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
The best approach is to create a "lock view" which is a UIView that takes over the whole screen once the textField becomesFirstResponder. Make sure it's on top of all views (well, besides the textview, of course).
- (void)loadLockView {
CGRect bounds = [UIScreen mainScreen].bounds;
_lockView = [[UIView alloc] initWithFrame:bounds];
_lockView.backgroundColor = [UIColor clearColor];
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(lockViewTapped:)];
[_lockView addGestureRecognizer:tgr];
[self.view addSubview:_lockView];
}
- (void)lockViewTapped:(UITapGestureRecognizer *)tgr {
[_lockView removeFromSuperView];
[_textField resignFirstResponder];
}
Use UITapGestureRecognizer For Dismiss keyboard.
Write this code on your viewdidload().
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];[self.view addGestureRecognizer:tap];
and in dismissKeyboard method put this code.
-(void)dismissKeyboard
{
[TextFieldName resignFirstResponder];
}
I want to dismiss UIActionsheet when user taps anywhere else on screen. I don't want to
provide cancel button.
My code
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:sheetTitle delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
[sheet setTag:indexPath.row];
for (NSString *buttonTitle in buttonTitles)
{
[sheet addButtonWithTitle:buttonTitle];
}
[sheet showFromToolbar:self.navigationController.toolbar];
[sheet release];
[buttonTitles release];
Make your ActionSheet object global and then allocate it into your block. then you can dismiss it from outside touches event on your view.
add following block into your view.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[sheet removeFromSuperView];
sheet=nil;
}
hope this will help you
try this
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOut:)];
tap.cancelsTouchesInView = NO;
[actionSheet.window addGestureRecognizer:tap];
[tap release];`<br> `-(void)tapOut:(UIGestureRecognizer *)gestureRecognizer {
CGPoint p = [gestureRecognizer locationInView:self.actionSheet];
if (p.y < 0) {
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
}
}
It is UIActionsheet default feature to dismiss when touch outside. No Need of additional code.
[sheet showFromToolbar:self.navigationController.toolbar];
is making the problem I think. Change it to
[sheet showInView:[UIApplication sharedApplication].keyWindow];
Declare ActionSheet globally and then paste this code after the viewdidload
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
}
works 100%
As of iOS 5, iPad keyboard can undock/split.
But my custom keyboard can not undock when my app is first launched. Only after, say, an alert view is shown and dismissed, the keyboard becomes undock-able.
I made a test project based on the Single View Application template as follows:
MyViewController.m :
#import "MyViewController.h"
#import "MyEditor.h"
#implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyEditor *editor = [[MyEditor alloc] initWithFrame:CGRectMake(0, 640, 768, 100)];
editor.backgroundColor = [UIColor cyanColor];
[self.view addSubview:editor];
}
#end
MyEditor.m :
#import "MyEditor.h"
#import "MyKeyboard.h"
#implementation MyEditor
- (CGSize)intrinsicContentSize {
return CGSizeMake(UIViewNoIntrinsicMetric, 100);
}
- (UIView *)inputView {
return [MyKeyboard sharedKeyboard];
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self isFirstResponder]) {
[self resignFirstResponder];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alertView show];
}
else {
[self becomeFirstResponder];
}
}
#end
MyKeyboard.m :
#import "MyKeyboard.h"
#implementation MyKeyboard
+ (MyKeyboard *)sharedKeyboard {
static MyKeyboard *sharedKeyboard;
if (sharedKeyboard == nil) {
sharedKeyboard = [[MyKeyboard alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
}
return sharedKeyboard;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[super setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
[super setBackgroundColor:[UIColor yellowColor]];
}
return self;
}
#end
The test steps are as follows:
Launch the app.
Tap the editor, and the keyboard will show.
Verify that you can not move the keyboard by dragging the lower-right corner of it.
Tap the editor again, the keyboard will hide, and an alert view will show.
Dismiss the alert view.
Tap the editor a third time, and the keyboard will show.
Verify that now you can move the keyboard by dragging the lower-right corner of it.
Done.
I wonder how to make the keyboard undock-able at the very beginning after launch. Any info is appreciated!
I just spent most of a day tracking down a very strange case where calling resignFirstResponder on the active UITextField did not hide the keyboard, even though the textfield was the first responder. This happens when I push a view controller on top of another view controller with an active text field. The keyboard goes away (as expected). But if I bring the keyboard back by touching a textfield in the 2nd view controller, subsequent calls to resignFirstResponder have no effect.
Here's simple code to reproduce the issue. This code is a view controller with a nav bar button to hide the keyboard, and another to push another copy of itself (with a confirmation UIAlertView). The first copy works without problem. However, if you push a 2nd copy (when the first copy has a visible keyboard) it is impossible to dismiss the keyboard. This only happens if there is a UIAlertView (the confirmation) on the screen when the 2nd copy is pushed. If you remove the #define ALERT line, everything works.
Does anyone know what is happening here? It looks like the UIALertView window is somehow interfering with the keyboard and keeping it's window from disappearing, which then confuses the next view. Is there any solution here other than pushing the 2nd view controller on a timer after the UIALertView is gone?
Sorry for the complex description. This is runnable code. I hope that the code is clear.
#implementation DemoViewController
- (id) init {
if (!(self = [super init]))
return nil;
return self;
}
- (void) dealloc {
[_inputTextfield release];
[super dealloc];
}
- (void) loadView {
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_inputTextfield = [[UITextField alloc] initWithFrame:CGRectMake(0., 0., 320., 44.)];
_inputTextfield.borderStyle = UITextBorderStyleRoundedRect;
_inputTextfield.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
_inputTextfield.keyboardAppearance = UIKeyboardAppearanceAlert;
_inputTextfield.autocapitalizationType = UITextAutocapitalizationTypeNone;
_inputTextfield.autocorrectionType = UITextAutocorrectionTypeNo;
_inputTextfield.keyboardType = UIKeyboardTypeDefault;
[view addSubview:_inputTextfield];
self.view = view;
[view release];
}
- (void) viewWillAppear:(BOOL) animated {
[super viewWillAppear:animated];
UIButton *downButton = [UIButton buttonWithType:UIButtonTypeCustom];
[downButton setTitle: #"keyboard down" forState:UIControlStateNormal];
[downButton addTarget:self action:#selector(downButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[downButton sizeToFit];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:downButton] autorelease];
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
[nextButton setTitle: #"next" forState:UIControlStateNormal];
[nextButton addTarget:self action:#selector(nextButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[nextButton sizeToFit];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:nextButton] autorelease];;
}
- (void) viewWillDisappear:(BOOL) animated {
[super viewWillDisappear:animated];
[_inputTextfield resignFirstResponder];
}
- (void) downButtonPressed:(id)sender {
[_inputTextfield resignFirstResponder];
}
#define ALERT
- (void) alertView:(UIAlertView *) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex {
if (alertView.cancelButtonIndex == buttonIndex) {
return;
}
[self _nextButtonPressed];
}
- (void) _nextButtonPressed {
DemoViewController *nextViewController = [[DemoViewController alloc] init];
[self.navigationController pushViewController:nextViewController];
[nextViewController release];
}
- (void) nextButtonPressed:(id)sender {
#ifdef ALERT
UIAlertView *alert = [[UIAlertView alloc] init];
alert.message = #"Next view?";
alert.cancelButtonIndex = [alert addButtonWithTitle:#"No"];
[alert addButtonWithTitle:#"Yes"];
alert.delegate = self;
[alert show];
[alert release];
#else
[self _nextButtonPressed];
#endif
}
If you had bad luck resigning your first responders, here are a few solutions that might help:
Determine who has remained the first responder after your last call to resign first responder.
Try resigning all first responders by a single call to self.view (container view)
[self.view endEditing:YES];
ONLY if you've tried all the above methods and none worked, consider using this workaround.
-(BOOL)textViewShouldEndEditing:(UITextView *)textView {
NSArray *wins = [[UIApplication sharedApplication] windows];
if ([wins count] > 1) {
UIWindow *keyboardWindow = [wins objectAtIndex:1];
keyboardWindow.hidden = YES;
}
return YES;
}