UIKeyboardTypeNumberPad dismiss keyboard - objective-c

How is a user suppose to indicate that he/she is done typing if the keyboard is of type UIKeyboardTypeNumberPad? There's no return/done button so how do I know the user wants to dismiss the keyboard?
Thanks

After researching this problem for a while, I found no really satisfactory answers. Some solutions hack a "Done" button, but that doesn't work well for localized applications. My apps don't use any words so I definitely don't want a "Done" button.
As mentioned by taskinoor it is convenient for editing to end if the view is touched elsewhere. That's what I did, and here is code showing the details:
Creating the textField programmatically:
aTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[aTextField addTarget:self action:#selector(c1Update) forControlEvents:UIControlEventEditingDidEnd];
aTextField.keyboardType = UIKeyboardTypeNumberPad;
[yourView addSubview:aTextField];
c1Value = aTextField; // I like to keep a pointer for UI updates, alpha etc.
What happens in c1Update:
- (void)c1Update {
[[self brain] setC1:[c1Value.text intValue]]; // update the model
}
Gesture recognizer on view:
- (void)viewDidLoad {
[super viewDidLoad];
[self updateViewColors];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped)];
tapRecognizer.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tapRecognizer];
}
- (void) viewTapped {
if (c1Value.isFirstResponder) {[c1Value resignFirstResponder];} // dismisses keyboard, which causes c1Update to invoke.
}

You can either provide a cancel/hide button (outside the keypad) or hide that when touched anywhere outside the keypad. These two are common practices.

try this. it might help you
hide the keypad when touched the screen.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
}

Related

iOS10 UITextView touch event crash

I have a very strange issue, UITextView touch event crash on double tap whereas same code works with < iOS10 version. (It means below iOS10 version there is no crash for press gesture recognizer)
Actually, I am adding the double tap and log press gesture based on permission. If the user has permission to comment then add gestures in viewDidLoad methods. Comment is allowed only with double tap or long press
singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureAction:)];
singleTapGesture.numberOfTapsRequired = 1;
// adding gesture to open window for commenting only when he has writing access
if (canComment) {
longPressgesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGestureAction:)];
longPressgesture.minimumPressDuration = 0.2;
doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doDoubleTap:)];
doubleTap.numberOfTapsRequired = 2;
}
On single tap
-(void)singleTapGestureAction:(UITapGestureRecognizer*)tapGestureRecognizer{
if (isSingleTapped) {
isSingleTapped = NO;
return;
}
isSingleTapped = YES;
UITextView *textView = (UITextView *)tapGestureRecognizer.view;
[self.commentView becomeFirstResponder]; // becomeFirstResponder
}
On double tap
-(void)doDoubleTap:(UITapGestureRecognizer*)tapGestureRecognizer
{
UITextView *textView = (UITextView *)tapGestureRecognizer.view;
[self.commentView becomeFirstResponder]; // becomeFirstResponder
// To show the UIMenuController menu
[self setCommentMenuToolTipWithRect:completeRect];
}
NOTE: I am adding [self.commentView becomeFirstResponder]; on every gesture action
UITextView delegate methods
- (void)textViewDidBeginEditing:(UITextView *)inView
{
[self.commentView becomeFirstResponder];
range=[self.commentView selectedRange];
}
USE CASE:
When I double tap to select any word then APP CRASH and UIMenuController does not appear,
but if I add the following line app does not crash
- (void)textViewDidChangeSelection:(UITextView *)textView{
[textView resignFirstResponder];
} // app does not crash
and UIMenuController appears with comment menu items that's great. I was happy that I have fixed the crash issue.
But there is another problem, when I press outside, menu hides and
select any word AGAIN then It does not appear SECOND time.
I have tried all the possible way to show the menu for returns
YES/TRUE to canBecomeFirstResponder. I know, there has to be a view
that claims firstResponder for the menu to show. but how ?
On second time touch, not even calling any gesture recognizer method
From the logs it is clear that when double tap is recognized, same touch update is also sent to another gesture recognizer, which fails.
So, a simple solution would be to avoid detection of other gestures on double tap.
This can simply be achieved by making all other gestures on commentView require doubleTap to fail using requireGestureRecognizerToFail. just add the condition in addGestureToTextView method as shown below.
if (withDoubleTap && self.canScreenPlayEdit) {
[self.commentView removeGestureRecognizer:singleTapGesture];
[self.commentView addGestureRecognizer:doubleTap];
[self.commentView addGestureRecognizer:longPressgesture];
for (UIGestureRecognizer *recognizer in self.commentView.gestureRecognizers) {
[recognizer requireGestureRecognizerToFail:doubleTap];
}
}
This does solve the crash and also shows the menu without calling resignFirstResponder in textViewDidChangeSelection.
However, there seem to be many issues in your code. PLSceneDetailsVC is too complicated and you need to simplify the code. You need to streamline the gesture management or you will end up facing many more such issues.
longPressgesture.minimumPressDuration = 0.2;
My guess the problem is here. 0.2s is way too small to be used for longPress. Probably both were triggered (longPress and double tap).
Change it to higher like 1.5s.

Getting the UIButton that was double-tapped from UIGestureRecognizer's action method

I wrote a fairly long action method connected to several UIButtons, and now I've realised I would like to have something different happen if I tap one of the buttons twice. So I am setting up two gesture recognizers:
UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnce:)];
UITapGestureRecognizer *tapTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTwice:)];
tapOnce.numberOfTapsRequired = 1;
tapTwice.numberOfTapsRequired = 2;
[tapOnce requireGestureRecognizerToFail:tapTwice];
[self.mybutton addGestureRecognizer:tapOnce];
[self.mybutton addGestureRecognizer:tapTwice];
then, I implement the methods:
- (void)tapOnce:(UIGestureRecognizer *)gesture{
//Do what you were already doing
}
- (void)tapTwice:(UIGestureRecognizer *)gesture{
// Some new functionality
}
Now, I don't have a problem with the new functionality. Where I get stuck is trying to get the tapOnce: method to do what my button was already doing. I need to know which button was tapped, so I can't use this:
[myButton sendActionsForControlEvents: UIControlEventTouchUpInside];
I also tried the old:
for (button in myArrayOfButtons){
[button sendActionsForControlEvents: UIControlEventTouchUpInside];
}
No luck either.
Then I went the way of actually creating a separate method for the implementation of my button, so what was:
- (IBAction)buttonPressed:(id)sender {
//my functionality...
}
became:
- (IBAction)buttonPressed:(id)sender {
[self myMethodwithSender:sender];
}
-(void)myMethodwithSender: (id)sender{
// my functionality
}
So that worked in itself, but when I try to put the tap once and twice into play I get stuck. I tried putting my new method in the method for tap once:
- (void)tapOnce:(UIGestureRecognizer *)gesture{
[self myMethodwithSender:sender];
}
but of course there is no sender in this method so it doesn't work (right?)
Then I tried changing this:
UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnce:)];
to this:
UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myMethodwithSender:)];
Which doesn't work either. So I am not sure how to do this. Any suggestions welcome.
With:
- (void)tapOnce:(UIGestureRecognizer *)gesture{
[self myMethodwithSender:sender];
}
If myMethodWithSender doesn't use sender, you can send nil. If it needs it to be the button, gesture.view should be that button (if you attached the recognizer to the button)

UIView Modal Popup with Embedded UITableView with UIToolbar, Toolbar moves with Table

This is driving me insane! (ios 5+, ARC)
Pretty simple concept here:
I have a UIView with an embedded UITableView, when clicking on a specific cell, I have iOS launch a modalview with a segue.
This modalview, is a UIView with an Embedded UITableView in it, filled with names from a data source. You can choose multiple items in this view (using cellaccessory: checkmark)
The Goal
Get some sort of "Done" button to show up
Ok, so after much running around, I am to understand that Modal windows do not, in fact, allow navigationController items. No toolbars, no Navigationbars by default.
Ok, so I'll create my own.
- (void)viewDidLoad
{
[super viewDidLoad];
NSInteger tbHeight = 50;
UIToolbar *tb = [[UIToolbar alloc] initWithFrame:CGRectMake(0, (self.view.frame.size.height - tbHeight), self.view.frame.size.width, tbHeight)];
tb.translucent = YES;
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneAction:)];
NSArray *barButton = [[NSArray alloc] initWithObjects:flexibleSpace,doneButton,nil];
[tb setItems:barButton];
[self.view addSubview:tb];
barButton = nil;
//....
}
Simple enough right?
Well, the toolbar does show up, for sure. BUT, it doesnt stick to the bottom like its supposed to. In fact, when you scroll the embedded tableview up and down, the UIToolbar goes with it, almost like its stuck on the tablevie somehow.
Ive been looking for hours for solutions, I've come across nothing. Wondering if anybody here has any ideas?
If you need more information, please by all means, enquire :)
It's strange that your toolbar is scrolling with the table if it's a UIViewController subclass, unless you've assigned a UITableView to self.view or something... But since it is, this is what I do when adding a fixed item to a table view:
-(void) scrollViewDidScroll:(UIScrollView *)scrollView {
tb.frame = CGRectMake(0, self.view.bounds.size.height-tb.bounds.size.height+scrollView.contentOffset.y, self.view.bounds.size.width, tb.bounds.size.height);
}

Handling Multiple Gestures on a View

Is there any way to detect a single tap vs. a scrolling gesture on a UIWebView?
I have a UIWebView, that contains rich text that many times, scrolls, if there is a lot of text content. I need to add a new feature that will allow the user to tap the UIWebView to get different content.
The problem is, my solution for this was to place a clear custom button on top of the UIWebView, which handles the tap but kills the scrolling feature. How do the cool kids do this type of thing?
Thanks
I solved this with a gesture recognizer. This eliminates the need for the UIButton overlay altogether.
//Handle taps on the UIWebView
self.singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(**tapDetected:**)];
singleTap.numberOfTapsRequired = 1;
singleTap.delegate = self;
[self.readAboutItView addGestureRecognizer:singleTap];
//Set up the event handler
- (IBAction)**tapDetected:**(UIGestureRecognizer *)sender {
//Do something with the content
[self webViewTouched:self];
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return YES;
}
-(BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}

Two finger tap on UIButton

I've got a UIButton in my application called myButton. I'd like to react to a single finger tap and a two finger tap on the button differently. However, from what I understand UIButton objects are only able to detect single finger touches touchDown, touchUpInside, etc. After doing some research, it looks like I'll have to use the touchesBegan method and just check to see if both of the fingers are within myButton frame. Is there any easier way to do this? Thanks!
Yes it is! By using UITapGestureRecognizer you can do something like this
- (void)viewDidLoad {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)]
tap.numberOfTapsRequired = 2;
[myButton addGestureRecognizer:tap];
[tap release];
}
- (void)tap:(UITapGestureRecognizer *)gesture {
NSLog(#"Tap!");
}