hiding keyboard ios [duplicate] - ios

This question already has answers here:
Dismiss keyboard on touch anywhere outside UITextField
(8 answers)
Closed 9 years ago.
I have a few text inputs and I can hide the keyboard whenever I touch the background, but only when I have been entering into the first text box name textField1. now this code should be simple but I just can't seem to get it.
-(IBAction)backgroundTouched:(id)sender {
[textField1 resignFirstResponder];
[buildLength resignFirstResponder];
[buildWidth resignFirstResponder];
[ridgeWidth resignFirstResponder];
[rafterWidth resignFirstResponder];
[hipWidth resignFirstResponder];
[eaveOverhang resignFirstResponder];
[spacing resignFirstResponder];
}

If you want to hide the keyboard when you tap a button and you have more than one UITextFields in your view, then you should use:
[self.view endEditing:YES];
Tap anywhere on the view, and the keyboard will disappear.

Try this:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[[self view] endEditing:YES];
}

You can also iterate through an array of views (such as your UIView's subviews) and manually resign the keyboard, this is good if you dont want to resign on ALL the subviews within your parent UIView.
- (void)viewDidLoad
{
self.view.userInteractionEnabled = TRUE;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//Iterate through your subviews, or some other custom array of views
for (UIView *view in self.view.subviews)
[view resignFirstResponder];
}

You can try UITouch method, and in this set your text field object and call resignFirstResponder
when ever you touch on the screen the keyboard will resign, I hope this will work for you.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[currentSelectedTextField resignFirstResponder];
}

Related

iOS Keyboard doesn't resign until after view transition

I have set this UIViewController to be the delegate for the UITextField in the viewDidLoad with this line: self.nameInputTextField.delegate = self;.
I have set the delegate on the class as well by adding <UITextFieldDelegate> to the #interface declaration.
When I select the nextButton, in the method that is called, I have tried [self.nameInputTextField resignFirstResponder] as well as [self.view endEditing:YES] one line before I push the new view controller.
The rest of the class does not manipulate the firstResponder.
I've also implemented the UITextField delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.nameInputTextField resignFirstResponder];
return NO;
}
I haven't found any related questions after extensive searching. There are many similar ones about resigning keyboards, but not regarding the timing of the keyboard resignation being postponed until after the view transition is complete. Note- if you reload this url in your browser, you'll see the gif again from the beginning.
Hide keyboard anywhere in ios :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
OR
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Resign your keyboard on viewWillDisappear and the problem should be solved.
Edit
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.nameInputTextField.text = #"";
[self.nameInputTextField resignFirstResponder];
}

How to prevent table view from not selecting the cell when keyboard is up

I have an app where there is a search field on top nav bar. When the user taps on the search field, the keyboard comes up and the background is greyed out. However at this point if the user taps on a cell in the table view, then the keyboard goes away and the cell drills down to the next screen. .how do i prevent this? The only way I can think of is to check if the keyboaard is present and if so then just dismiss the keyboard and do nothing. Is there any other way around it?
I also have buttons in the tableview cell which also activates when it is tapped when the keyboard is up. So I guess I need a generic way of knowing if the keyboard is up and just dismiss and not do any action.
Implement UITextViewDelegate and UITextFieldDelegate
Something like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([theTextView isFirstResponder] && [touch view] != theTextView) {
[tableView setUserInteractionEnabled:NO];
[textField resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}
- (void)textViewDidEndEditing:(UITextView *)textView {
[tableView setUserInteractionEnabled:YES];
}

UIControl tracking touch that started on a different UIControl

I am making a custom iOS keyboard and have a UIControl subclass to represent my button. I am trying to get the same behaviour as the normal iOS keyboard:
User begins touch on one button
User drags over other buttons (need to detect this so they can highlight/dehighlight accordingly)
Register the actual keyboard "press" when the user lifts their finger; that is, the touch ends
I am testing using the touch tracking methods like this:
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super beginTrackingWithTouch:touch withEvent:event];
NSLog(#"Begin for %#", [self label]);
return YES;
}
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super continueTrackingWithTouch:touch withEvent:event];
NSLog(#"Continue for %#", [self label]);
return YES;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
NSLog(#"End for %#", [self label]);
}
These methods are all called, except they are only ever called on the UIControl where the touch began.
What is the best way to recognise touches coming and going across all my buttons? Do I have to do it all via the parent view?
I'll select a better answer if offered... but in case anybody finds this by search, I've managed to get what I need this way:
Set userInteractionEnabled to NO for the button class (UIControl subclass)
Don't override any touch methods in the button class
Implement touchesBegan:withEvent:, touchesMoved:withEvent: and touchesEnded:withEvent: in the view controller
On each event, extract the location from the UITouch object
Iterate over all of the button subviews and find the one containing the touch location:
- (MyButton *)buttonForTouch:(UITouch *)touch
{
CGPoint windowLocation = [touch locationInView:keyboardView];
for (MyButton *button in buttons) {
if (CGRectContainsPoint([button frame], windowLocation)) {
return button;
}
}
return nil;
}
Having determined which button the user is interacting with, make the view controller send messages to the relevant buttons to adjust their appearance
If appropriate, keep a reference to the UITouch instance in touchesBegan:withEvent: so you can be sure that you're tracking the same one in the other methods
I think that you should have a single big UIControl which has different subviews (like UIButton) but tracks touches by itself like you did already but finds out which subview to highlight depending on the touch position.

ResignFirstResponder not working.

I want to implement a function that once I touch the table view, the search bar on the top of the view will resignFirstResponder and the keyboard will retrieve from the view. I relate the follow code to the tableView in the xib file but it seems not working.
- (IBAction)backgroundTap:(id)sender
{
NSLog(#"test : did touch down");
[_searchBar resignFirstResponder];
}
I try another way of implementation by adding the following code in the .m file, but still not working.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"test : did touch down");
UITouch *touch = [touches anyObject];
UIView *view = (UIView *)[touch view];
if (view == self.view) {
[_searchBar resignFirstResponder];
}
}
Hope that someone could help.
Just do..
[Self.view endEditing:YES];
Try doing exactly what you are doing, but call resignFirstResponder twice. I found that I must do that as of iOS 7.

TouchesEnded and TouchesCancelled not called

Okay I tested the following with the tabbed application template on Xcode 4.5/iOS 6.
Created a tabbed application.
Created a UIButton subclass called SampleButton and implemented
the following mothods:
- (void)touchesBegan:(NSSet *)touches
withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches
withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
}
- (void) touchesMoved:(NSSet *)touches
withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches
withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}
Added this SampleButton to the first tab.
Added breakpoints to all the touch methods.
Run on device.
Tested that all the touch methods are firing as expected.
Now touch the SampleButton and then also press the second tab.
RESULT: View switches to second tab but touchesCancelled and/or touchesEnded are never called in SampleButton. Shouldn't one or the other of those fire if the view changes while I'm touching that button? This is proving to be a huge issue because, in my app I'm playing a sound while that button is down and it never stops playing if the user switches tabs while pressing it. Seems like this used to work fine in iOS3 and iOS4.
It appears that when a view is removed from its window, it dissociates itself from any touches that were associated with it. So when the touch finally ends, the system doesn't send touchesEnded:… or touchesCancelled:… to the view.
Workaround by disabling tab switching
If you want to just disable tab switching while the button is pressed, you can do that by giving the tab bar controller a delegate and having the delegate return NO from tabBarController:shouldSelectViewController:. For example, in the your test app, you can have FirstViewController make itself the tab bar controller's delegate:
- (void)viewWillAppear:(BOOL)animated {
self.tabBarController.delegate = self;
}
And the view controller can allow the tab bar controller to select a tab only when the button is not pressed (highlighted):
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return !_button.highlighted;
}
Workaround by detecting button highlight resetting to NO
When the button is removed from its window, it resets its highlighted property to NO. So one generic way to work around this problem is by using key-value observing (KVO) to monitor the button's state (instead of relying on the button to send you actions). Set yourself up as an observer of the button's highlighted property like this:
static int kObserveButtonHighlightContext;
- (void)viewDidLoad {
[super viewDidLoad];
[_button addObserver:self forKeyPath:#"highlighted"
options:NSKeyValueObservingOptionOld
context:&kObserveButtonHighlightContext];
}
- (void)dealloc {
[_button removeObserver:self forKeyPath:#"highlighted"
context:&kObserveButtonHighlightContext];
}
I discovered in testing that the button sends an extra KVO notification when it's removed from the window, before it resets its highlighted property back to NO. So when handling the KVO notification, check that the value has actually changed:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == &kObserveButtonHighlightContext) {
if ([change[NSKeyValueChangeOldKey] boolValue] != _button.highlighted) {
[self updatePlaybackForButtonState];
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Finally, start or stop playback according to the highlighted property of the button:
- (void)updatePlaybackForButtonState {
if (_button.highlighted) {
NSLog(#"start playback");
} else {
NSLog(#"end playback");
}
}
Subclassing the button seems like the hard way to do this. Just tell the audio player to stop playing in the viewDidDisappear:animated: method, as R.A. suggested.
I worked around this by setting targets for the actions instead of using the touch methods:
[self addTarget:self action:#selector(handleKeyPressed) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:#selector(handleKeyReleased) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:#selector(handleKeyReleased) forControlEvents:UIControlEventTouchCancel];
These seems to get fired correctly even when the view swaps out.

Resources