I study iOS SDK using this book and in 4 Chapter, when it tells you how to hide number pad with background tap I have a problem. I do that author says but nothing happened. How I can do this?
What book's author says:
1)Create new method backgroundTap in ViewController.h
- (IBAction)touchBackground:(id)sender;
2)Add method in ViewController.m
-(void)touchBackground:(id)sender{
[nameField resignFirstResponder];
[numberField resignFirstResponder];}
3)Change class identity of View object in Interface Builder(as I understand in Xcode 4 its Control) from UIView to UIControl
4)Connect TouchDown method in events list with File's Owner and check method backgroundTap.
This is my code samples
ViewController.h
ViewController.m
P.S. I'm sorry for my English, I translated all information from the book to english because I have russian translate.
I think you might make this simpler by just implementing a method like this:
- (IBAction)backgroundTouched:(id)sender {
[self.view endEditing:YES];
}
make the background view UIControl instead of UIView in interface builder and hook the touches up event to this method.
Have a look at this small example project. I have done exactly this in the secondViewController where touching the background dismissed the keyboard. You can also see how I have changed the background to a UIControl in secondViewController.xib
Something you might want to try, without changing the background view, is:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[nameField resignFirstResponder];
[numberField resignFirstResponder];
}
You may have done Step 4 ("Connect TouchDown method in events list with File's Owner and check method backgroundTap") incorrectly. Include an NSLog in your touchBackground method to check whether the method is being called.
-(void)touchBackground:(id)sender{
[nameField resignFirstResponder];
[numberField resignFirstResponder];
NSLog(#"touchBackground was called");
}
If the message ("touchBackground was called") doesn't show up in your console, then you known touchBackground is not being called.
Related
I'm writing an app in which I want to dismiss the keyboard by clicking in the background. I know I need to type in the following code somewhere after dragging one of the "Sent Events" dots to somewhere on the view controller. Assume for this example that the text field is called textField.
-(IBAction)backgroundTap:(id)sender {
[textField resignFirstResponder];
}
Which dot do I need to drag from in "Sent Events" and to where? I know that this is the code that will work, but I can never remember which dot to use and where to drop it on the screen.
Thank you!
Usually when I need to resign first responder in the event of a background tap, I overwrite the - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event UIViewController method, and in there, I resign first responders. I'm not sure if this is possible using Interface Builder in one quick action.
Use button in background to click out..and write simple code for click EVENT TOUCH UP INSIDE
-(IBAction)backgroundbuttonpress:(id)sender
{
[textField resignFirstResponder];
}
connect action to button...and make sure that You have declared UITextFieldDelegate in .H file
Actually, I remember it now.
I need to use Touch Down with a type of id and call it backgroundTap. Thanks, myself. :P
I would recommend adding a UIGestureRecognizer to you background view. Like this
- (void)viewDidLoad {
[super viewDidLoad];
// Do whatever you want...
UITapGestureRecognizer *screenTapped = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissKeyboard)];
screenTapped.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:screenTapped];
}
- (void)dismissKeyboard {
[self.view endEditing:YES];
}
Now the keyboard will be dismissed when the user taps the background view.
Hope it helps!
I'm trying to get rid of the keyboard when the user touch outside my UITextField, by using this method:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[mainTextController resignFirstResponder];
[super touchesBegan:touches withEvent:event];
}
However, this seems to call a method that is called after pressing the return button on the keyboard, but I just want the keyboard to vanish, not to press return for me.
How can I accomplish that?
Thanks!
EDIT: tGilani's answer is the most straight-forward way, works like a charm, without changing to UIControl. But I guess jonkroll's answer also works.
try
[self.view endEditing:YES];
Update:
Take a boolean value and set it to false in init method. In your textFieldShouldReturn delegate method method, execute the code if it is false, skip otherwise
- (BOOL) textFieldShouldReturn:(UITextField*)textField
{
if (!boolean)
{
// YOur code logic here
}
boolean = false;
}
in your method where you call the endEditing method, set boolean to true.
boolean = YES;
[self.view endEditing:YES];
Here's how I've handled this before. First create a method on your view controller that will dismiss the keyboard by resigning first responder status on your text field:
- (IBAction)dismissKeyboard:(id)sender
{
[mainTextController resignFirstResponder];
}
Next, in your storyboard scene for your ViewController (or nib, if you are not using storyboards) change the class of your ViewController's view property from UIView to UIControl. The view property is effectively the background behind your other UI elements. The class type needs to be changed because UIView cannot respond to touch events, but UIControl (which is a direct subclass of UIView) can respond to them.
Finally, in your ViewController's viewDidLoad: method, tell your view controller to execute your dismissKeyboard method when the view receives a UIControlEventTouchDown event.
- (void)viewDidLoad
{
[super viewDidLoad];
UIControl *viewControl = (UIControl*)self.view;
[viewControl addTarget:self action:#selector(dismissKeyboard:) forControlEvents:UIControlEventTouchDown];
}
EDIT:
Part of your concern seems to be that textFieldDidEndEditing: is called when the keyboard is dismissed. That is unavoidable, it will always be called whenever a text field loses focus (i.e. first responder status). It sounds like your problem is that you have put code to perform when the user clicks the return button in textFieldDidEndEditing:. If you do not want that code to run when the user touches outside of the text field, that is not the proper place to put it.
Instead, I would put that code in a separate method:
- (IBAction)textFieldReturn:(id)sender
{
if ([mainTextController isFirstResponder]) {
[mainTextController resignFirstResponder];
// put code to run after return key pressed here...
}
}
}
and then call that method via Target-Action when your text field sends the control event UIControlEventEditingDidEndOnExit.
[mainTextController addTarget:self action:#selector(textFieldReturn:) forControlEvents:UIControlEventEditingDidEndOnExit];
Note that UIControlEventEditingDidEndOnExit is different than UIControlEventEditingDidEnd. The former is called when editing ends by the user touching outside the control, the latter is called when editing ends by the user pressing the return key.
You need to change your ViewController's view property from UIView to UIControl using the Identity Inspector:
From there, you simply create an IBAction and tell the textfield to dismiss (which I am assuming is your mainTextController). If mainTextController is not the textfield you want the keyboard to dismiss on then change the resignFirstReaponder method to your textfield like so.
- (IBAction)backgroundTap:(id)sender {
[myTextField resignFirstResponder];
}
then from there go back into your View Contoller's .xib file and connect the action to the Control View and select "Touch Down".
I want to hide the keyboard when i press any key other than the return key .
For example when the user presses the character 'n' on keyboard , keyboard should disappear.
Please provide me a suitable answer as soon as possible.
Thanks in advance.
You may try UIKeyInput protocol. To catch a insert with insertText
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIKeyInput_Protocol/Reference/Reference.html
Have you used protocols?
EDIT:
Then you can use method
[textField resignFirstResponder];
To hide the keyboard
EDIT2: Protocols
In short, the interface for class that you want to respond to the protocol must be declare as (in YourClass.h):
#interface YourClass:NSObject<UIKitInput>
then, you have to implements the protocol methods in YourClass.m:
#pragma mark -
#pragma mark UIKeyInput Protocol Methods
- (BOOL)hasText {
.....
return NO;
}
- (void)insertText:(NSString *)theText {
...;
}
- (void)deleteBackward {
....
}
Good Luck!
For that, you have to create a custom keyboard or you have to override the Keyboard methods. But you cannot override. Because You do not know, in which method and what code is to sense that key pressing in that frameworks. So better write a custom keyboard anyway.
The keyboard hides when the text field resigns first responder. The textfield delegate is told when a key is pressed (textField:shouldChangeCharactersInRange:replacementString:). If you need any more detail than that, please put a bit more effort into your question and show us what you have tried so far.
We're trying to figure out how to get the keyboard to hide, but we're having problems getting the textFieldShouldReturn to fire. Why?
This is what has been done:
*.h
#interface MultiSalesViewController : UIViewController <UITextFieldDelegate>
*.c
txtCardNumber.delegate = self;
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField setUserInteractionEnabled:YES];
[textField resignFirstResponder];
return YES;
}
Also, the textField has its delegate set to Files Owner in Interface Builder. One odd thing, is that the viewController's - (void)textFieldDidEndEditing:(UITextField *)textField is working.
How to get the hiding of the keyboard working?
I had the exact same issue and it was because I forgot to set the delegate for the text field in interface builder to 'files owner'.
I had the same problem and, as Warren Crowther suggested, I managed to solve it by holding down CTRL and dragging from the TextBox to the "File's Owner" label.
(Gosh, I miss Visual Studio sometimes...!!)
(Apologies for repeating what's already been said, but I thought a screenshot might be useful !)
I had the delegate set and everything. But I was using a UITextView instead of UITextfield...
Perhaps this will help someone trying to figure why delegate methods are not fired.
I see you put it in your code, but for future visitors, add this to your code:
yourTextField.delegate = self;
I think you are using xib. If so You also need to set delegate over there. Do Right Click on your UITextfiled in xib and you will have delegate option drag it to your file owner.
be sure that your MultiSalesViewController implements the UITextFieldDelegate protocol:
#interface MultiSalesViewController : UIViewController <UITextFieldDelegate>
try adding [self becomeFirstResponder]; after [textField resignFirstResponder];
edit:
just another thought.. does your UITextField have a value set for returnKeyType?
txtCardNumber.returnKeyType = UIReturnKeyDone;
i'm not sure if this has to be set for the function to work
following is answer from Mike Gledhill and Warren Crowther updated with xcode 5 screenshot.
(to set UITextField delegate, press and hold ctrl + drag from the UITextField to the "File's Owner" yellow button, shown in image below. if UITextField delegate not set, textFieldShouldReturn method never gets called).
I had everything wired up just right and - (BOOL)textFieldShouldReturn:(UITextField *)textField was still not being called!
As a work around I configured a method to fire on 'EditingDidEnd':
Go to Connection Inspector and connect delegate to view controller .thats it .
Checklist to get it to work:
Did you set your controller as delegate to UITextField Instance?
Make sure controller is not being deallocated by either assigning to property (Autorelease) or explicit retaining it.
I've just started with xcode and objective-c and did some very basic apps, but what i'm having problem with is very basic this. the keyboard return button not hiding the keyboard.
I've searched the internet for the solution and all they say is to connect delegate to the file's owner and add the function and it should work, i did that and nothing is working.
I have an ok button and it is working and also clicking on any free space on the screen is working, just the return button....
I am using the simulator, not testing on iphone yet. (xcode 3.2.5 64 bit with the 4.2 simulator).
This is the line of code that should connect the delegate to every textFiled.
1. i've tried already to return both YES and NO, didn't work.
2. i've tried both a specific object name for the textField and this general way, didn't work.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
In the: basic view controller connection -> connections -> outlets, i have the: delegate -- File's Owner. and in the file's owner in referencing outlets there is: delegate - Round style text.....
EDIT - i forgot to mention before, i've check and the method isn't being called!!!
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"Working!!!");
[textField resignFirstResponder];
return YES;
}
what should i do to make it happen? that is why people say to connect the delegate, but in my case it is connected and not triggering the function...i know it is kind of dumb question but for a nobie like me the solution is not obvious...
OK, another Edit - with all my code: just can't understand what to do....
This is: basicViewController.h:
#import <UIKit/UIKit.h>
#interface basicViewController : <#superclass#> <UITextFieldDelegate>
#interface basicViewController : UIViewController <UITextFieldDelegate> {
//every object that we want to interact with (like text field or lable) is call an outlet!!!!
//here we define the outlets for our program
IBOutlet UITextField *txtName;
IBOutlet UILabel *lblMessage;
}
//here are the getters and setter for our outlets
#property (nonatomic, retain) IBOutlet UITextField *txtName;
#property (nonatomic, retain) IBOutlet UILabel *lblMessage;
//method decleration for the OK button action
- (IBAction) doSomething;
//method for hiding the keyboard when clicking on empty area in the app
//we will put an invisible button on all area and clicking on it will make keyboard disapear
- (IBAction) makeKeyboardGoAway;
#end
This is basicViewController.m:
#import "basicViewController.h"
#implementation basicViewController
//synthesizeing the objects that we made' this will create the getter and setters automaticly
#synthesize txtName;
#synthesize lblMessage;
- (IBAction) doSomething{
// makeing keyboard disapear when pressing ok button (doing that form the text field)
//when pressing the OK button, the keyboard will disapear and when clicking in the text field it will show again
[txtName resignFirstResponder];
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#",txtName.text];
//the objective-c way for setting the test in the text field
[lblMessage setText:msg];
//the regular object oriented way
//lblMessage.text = msg;
[msg release];
}
- (IBAction) makeKeyboardGoAway{
[txtName resignFirstResponder];
}
//when clicking the return button in the keybaord
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"Working!!!");
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Maybe now i am more clear, sorry i didn't do it before.
Any one has an idea what am i doing wrong? it should be pretty strait forward.....
EDIT - Adding an image of all the elements, i hope that will help to help me :-)
10x a lot for every one that is trying to help....i really like this framework, it is so great after c++ and java, python and many other...and i am working with a book, but it is for ios 3.1, maybe that is the problem.....
Firstly you should check if textFieldShouldReturn: is actually being called by adding an NSLog statement or breakpoint at the beginning of the method.
Once that's out of the way, try an manually declare that your view controller conforms to <UITextFieldDelegate> protocol in your interface file:
#interface YourClass : ... <UITextFieldDelegate>
Also declare a property & outlet for your UITextField, make the appropriate connections in IB and manually declare self as the UITextField delegate with:
self.yourUITextFieldObject.delegate = self;
Once that's done see if your method above is now being called and make sure you return YES.
Just write one line in the
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
}
before return YES;
the final version will be as given below:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(#"%#",textField.text);
}
You need to assign the delegate of the textfields to your file owner. The textfields are sending the message, but doesn't have a delegate to respond to it.
Use the interface builder to do that.
You have to implement this method..
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Like Rog said, don't forget to register the textfield to the delegate, you can do this manually as he said but in Storyboard you can just control drag from all of your textfields to the view controller and register the delegate (choose delegate). Only the textfields that are registered can make use of all those methods.
So this line is important:
self.yourUITextFieldObject.delegate = self;
Or even more easy these days is to just use the storyboard:
textfield is in a subview? in this case, make sure textfield have as delegate the FileOwner.
put a log at the
- (IBAction) makeKeyboardGoAway
function. I think its this method everytime anything is tapped on the screen. In that case, you will need to send the touch event to the text field. Not sure how this is done but that should do it.
Else try removing the which takes care of tap(click) all over the view and try to do what you are doing.
Most likely the problem is that your actual view controller in the running application is not a "basicViewController" but a UIViewController that does not implement the UITextFieldDelegate-protocol.
What you've done in the interface builder by selecting your class "basicViewController" as the FilesOwner is just declaring the FilesOwner-object in your running application to be of type basicViewController; the actual object is not instantiated by this declaration and in your case it is not in the xib / nib.
Some other part of your code actually instantiates a view controller object and loads the xib / nib file. At that place, I guess your code is instantiating a UIViewController (typically by auto-generated code) and not an instance of your basicViewController; you simply have to change the class there.
Furthermore, this error often happens when using a UINavigationController or UITabBarController in the Interface Builder that is (should be) configured to instantiate and load other custom views. If you use such a higher-level controller, double-check that it is actually configured to use your basicViewController, not UIViewController when loading your view from the xib / nib.
Hope, that solves the issue!
Can you try this..
#interface ClassName : SuperClass < UITextFieldDelegate >
Use like this...
textfield.delegate=self;
and use the UITextFieldDelegate in .h class
You can always dismiss the keyboard when you don’t even know which view the text field is in by using:
Objective-C:
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder)
to:nil
from:nil
forEvent:nil];
Swift:
UIApplication.sharedApplication().sendAction("resignFirstResponder",
to:nil,
from:nil,
forEvent:nil)