Problem with dismissing the keyboard when focus leaves a UITextView - objective-c

I have 3 uitextfield in my project
I need to when tap inside one of them (uitextfield2 ) a custom subview appear , and need the key board to appear when tap on one another (uitextfield1 )
the problem is when I tab on uitextfield1 , the keypad appear and not go even I clicked return or tap on another uitextfield2
I need the keyboard to disappear when I click out of the uitextfield1 or when click return
I use the following code
- (BOOL)textFieldShouldReturn:(UITextField *)textField { // When the return button is pressed on a textField.
[textField resignFirstResponder]; // Remove the keyboard from the view.
return YES; // Set the BOOL to YES.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// [textField resignFirstResponder];
[self SelectModalityClick]; // will be called If i tapped inside the uitextfield2 to display the custom view
return NO;
}

When you create your UITextField instances, you can set the inputView to whatever UIView subclass you want with something like this.
UITextField *aTextField = [[UITextField alloc] initWithFrame:aRect];
aTextField.inputView = myCustomInputView; // Set this up in your viewDidLoad method
aTextField.delegate = self;
aTextField.tag = MyCustomInputView; // #define this as some integer
[self.view addSubview];
[aTextField release];
You shouldn't need to do anything special to make the correct input view appear, if you have a UITextField instance variable for the first responder, just assign it in textFieldShouldBeginEditing: and resign its first responder status in textFieldShouldReturn:.

Related

Switch from a UIPickerView to a Keyboard

I have a UIPickerView set up with an attached toolbar button that should allow the user to switch from a picker view to a keyboard view. The pickerView should slide down and a keyboard should slide up in it's place... Theoretically.
The pickerView appears when a user clicks the text field in textFieldDidBeginEditing.
elementPicker = [[UIPickerView alloc] init];
[elementPicker setDelegate:self];
elementPicker.showsSelectionIndicator = YES;
...
[_itemElementField setInputView:elementPicker];
When the user clicks the "Use Keyboard" button, I have a method to dismiss the picker and call the keyboard. I can dismiss the pickerview without a problem but CANNOT DISPLAY THE KEYBOARD!!
HELP!
Here is the method called when the user wants the keyboard:
-(void)useKeyboardClicked:(id)sender {
NSLog(#"'USE KEYBOARD' BUTTON CLICKED");
// DISMISS THE PICKER VIEW
[elementPicker removeFromSuperview];
[_itemElementField resignFirstResponder];
_itemElementField.inputAccessoryView = nil;
// SET ELEMENTPICKER TO THE DEFAULT KEYBOARD
elementPicker = UIKeyboardTypeDefault;
[_itemElementField setInputView:elementPicker];
// SHOW KEYBOARD
[_itemElementField becomeFirstResponder];
}
I'm grasping at straws now and need some help! I've even gone so far as to try to define a keyboard in the header file with
#property (strong, nonatomic) IBOutlet UIKeyboard *elementKeyboard;
but that doesn't work AT ALL.
for those that might have this issue in the future, the answer ends up being quite simple.
You need to reload the input view after resetting it to a keyboard with reloadInputViews.
Here's the code:
-(void)useKeyboardClicked:(UITextField *)sender {
NSLog(#"'USE KEYBOARD' BUTTON CLICKED");
[_itemElementField setInputView:UIKeyboardTypeDefault];
[_itemElementField becomeFirstResponder];
[_itemElementField reloadInputViews];
}
Here Is Solution Firstly you have to declare boolean variable checkFlag to keep record of useKeyboardClicked:
then
-(void)useKeyboardClick:(id)sender
{
if (checkFlag) {
checkFlag=false;
[txtField setInputView:nil];
[txtField reloadInputViews];
[txtField setKeyboardAppearance:UIKeyboardAppearanceDefault]; //you can set UIKeyboardAppearnce as Dark,light, alert instead of Default
[txtField setKeyboardType:UIKeyboardTypeDefault]; // you set decimal keyboard
} else {
checkFlag=TRUE;
[txtField setInputView:nil];
[txtField setInputAccessoryView:numberToolbar];
[txtField setInputView:pickerView];
}
}
One thing i m not total wrong but i can't set back picker view instead keyboard ..... try this i gave you hint ...

Some time cannot hide iOS keyboard and show UIPickerView

This is my .h
xxxx : UIViewController<UITextFieldDelegate>
and my .m
UITextField *quarterPicker = [[[UITextField alloc] init] autorelease];
[quarterPicker setFrame:CGRectMake(150, 370, 60, 30)];
[quarterPicker setText: #"Q1"];
quarterPicker.delegate = self;
and i use
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(#"textFieldShouldBeginEditing");
[textField resignFirstResponder];
[textField addTarget:self action:#selector(selectQuarterPicker:) forControlEvents:UIControlEventTouchDown];
return NO; // Hide both keyboard and blinking cursor.
}
When i touch to my textField, i alway see this log textFieldShouldBeginEditing
But some time, my Picker doesn't show. I use : https://github.com/TimCinel/ActionSheetPicker to make Picker.
I find out that, when i swipe my textFiled, my picker will display.
How can i fix this?
UPDATE: i put my UITextFiled insite UIScrollView
You are adding the target for the touch event after the first touch is made. So only the second will work. Why add this event? You can simply show the picker inside shouldBeginEditing without adding a touch event
Something like
[self selectQuarterPicker:self]; //assuming the parameter is the sender as you commented

NSTextField events and resigning first responder

I want to implement an NSTextField where when I click it, it selects all the text. (to give the user easy way to delete all current text)
when I finish editing it, either by pressing enter/tab or moving the mouse outside of it's rect, I will move the focus out of the field, and change it's alpha values to 0.5.
My Code:
H file:
#import <Foundation/Foundation.h>
#interface MoodMsgTextField : NSTextField<NSTextFieldDelegate>
#end
M file:
-(BOOL) becomeFirstResponder
{
NSLog(#"become first responder");
BOOL result = [super becomeFirstResponder];
if(result)
{
[self setAlphaValue:1.0];
[self performSelector:#selector(selectText:) withObject:self afterDelay:0];
}
return result;
}
-(BOOL) refusesFirstResponder
{
return NO;
}
-(BOOL) resignFirstResponder
{
NSLog(#"resigning first responder");
BOOL result = [super resignFirstResponder];
NSText* fieldEditor = [self.window fieldEditor:YES forObject:self];
[fieldEditor setSelectedRange:NSMakeRange(0,0)];
[fieldEditor setNeedsDisplay:YES];
[self setAlphaValue:0.5];
return result;
}
-(void)awakeFromNib
{
self.delegate = self;
[self setAlphaValue:0.5];
[self setBordered:YES];
[self setWantsLayer:YES];
self.layer.borderWidth = 0.5;
self.layer.borderColor = [[NSColor grayColor] CGColor];
}
- (void)controlTextDidChange:(NSNotification *)aNotification
{
NSLog(#"the text is %#",self.stringValue);
}
- (void)controlTextDidEndEditing:(NSNotification *)aNotification
{
NSLog(#"end editiing : the text is %#",self.stringValue);
[self.window makeFirstResponder:nil];
}
- (void)mouseEntered:(NSEvent *)theEvent
{
[self setWantsLayer:YES];
self.layer.borderWidth = 0.5;
self.layer.borderColor = [[NSColor grayColor] CGColor];
}
- (void)mouseExited:(NSEvent *)theEvent
{
[self setWantsLayer:YES];
self.layer.borderWidth = 0;
}
So, I have a few problem:
1.
When I press inside the NSTextField (when the focus is outside) it instantly becomes and resigns first responder and I get editing end message. Why is that ?
The log I get on click is this :
2011-08-02 18:03:19.044 ooVoo[42415:707] become first responder
2011-08-02 18:03:19.045 ooVoo[42415:707] resigning first responder
2011-08-02 18:03:19.104 ooVoo[42415:707] end editing : the text is
2.
When I press the enter key it just selects all text inside and doesn't move the mouse focus. When I press the tab is does seem to move focus, however neither of the two causes the resignFirstResponder to get called. Why ?
3.
None of the mouse event function are getting called. Do I need to to do something special for that ? I thought that since they are NSResponder's ones, I will get those for free by inheriting from NSTextField. Do I need NSTrackingInfo here as well ?
4.
Last but not least, for some reason, every couple letters, one letter seems to be bold.
I have no idea why.
I'd appreciate any help.
Thanks
I am not sure why this is happening in this case but you should read about the Field Editor concept. Basically a NSTextField does not handle its own input but uses an NSTextView called the field editor to accept input.
You need to react to the Enter key yourself. Take a look at the key handling documentation. Here is an answer with an example.
To get mouse events you can use NSTrackingArea. See the docs for Mouse Tracking.
I do not have any input on this except that sometimes text drawing can look bold when really what is happening is that the text is being drawn multiple times without erasing the background.

Obj C - resign first responder on touch UIView

I'm trying to get the keyboard to disappear when the screen is touched, a question that is answered all over stackoverflow. I was able to get the keyboard to disappear when the enter key was pressed thanks to a thread here. I'm not having luck on the background touch resigning the first responder. The method is being entered, I have an NSLog in the method saying, "in backgroundTouched" but the keyboard is still there.
I've tried making the UIView a UIControl class so I could use the touch event.
journalComment is a UITextView.
-(IBAction)backgroundTouched:(id)sender
{
[journalComment resignFirstResponder];
NSLog(# "in backgroundTouched");
}
I've also tried having a invisible button under everything that calles the backGroundTouched method. I think it maybe that I'm missing something in interface builder, but I'm not sure what.
Thank you for any help!
This is what works for the done button:
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
// Any new character added is passed in as the "text" parameter
if ([text isEqualToString:#"\n"]) {
// Be sure to test for equality using the "isEqualToString" message
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return FALSE;
}
// For any other character return TRUE so that the text gets added to the view
return TRUE;
}
I found the following code works best with my text view (not text field) without the delegate methods:
first you set up a tap gesture recognizer onto your view :
- (void)viewDidLoad{
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(tap:)];
tapRecognizer.delegate = self;
[self.view addGestureRecognizer:tapRecognizer];
}
and then in your tap method :
- (void)tap:(id)sender
{
// use to make the view or any subview that is the first responder resign (optionally force)
[[self view] endEditing:YES];
}
this should allow your keyboard to be dismissed when you anywhere on the view.
Hope this helps
Try this. We had this problem eariler, but eventually found the right solution.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[yourtextfield resignFirstResponder];
// you can have multiple textfields here
}
This should resolve the problem with the keyboard not dissapearing when pushing the background.

display popover when user click into text field?

Hi i have been following a book a how to display the popover when the user clicks on a toolbar button item. It works fine but I want to display the popover when user clicks into a textField. It seems like it would be some minor adjustment. Like changing the IBAction
"showPopover" method a bit. This is what the code looks like for that method:
- (IBAction)showPopover:(id)sender{
if(popoverController == nil){ //make sure popover isn't displayed more than once in the view
popoverController = [[UIPopoverController alloc]initWithContentViewController:popoverDetailContent];
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
popoverController.delegate = self;
}
}
There is a another instance method other than "presentPopoverFromBarItem" that is called
"presentPopoverFromRect".Would I use that instead? I tried to write the code for it but I'm not sure how to relate it to my TextField or how draw the rectangle needed.Can anyone help me with this?Thanks.
you have to use the textfields delegate method textViewShouldBeginEditing:
Something like this:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
if(popoverController == nil){ //make sure popover isn't displayed more than once in the view
popoverController = [[UIPopoverController alloc]initWithContentViewController:popoverDetailContent];
}
[popoverController presentPopoverFromRect:textView.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
popoverController.delegate = self;
return NO; // tells the textfield not to start its own editing process (ie show the keyboard)
}
For those who want to display a popover, but do not want to display the keyboard when the text field is tapped, here is the solution that I've always used (Notice this is different than the previous answers textFieldShouldBeginEditing):
/*
* Handle when text field is about to start edit mode
*/
- (BOOL)textFieldShouldBeginEditing:(UITextField *) textField
{
// Create popover controller if nil
[self.myPopover presentPopoverFromRect:textField.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
return NO;
}
Hope this helps!
if your textField is inside a table cell your popover will point to the top of the screen because the frame of the textField frame is in reference to the view that contains the textfield. So you need to give it the correct view reference. You need to use the textField.superview as your view reference.
- (BOOL)textFieldShouldBeginEditing:(UITextField *) textField
{
...
[self.myPopover presentPopoverFromRect:textField.frame inView:textField.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
return NO;
}
Yes, there is a presentPopoverFromRect method.
To wire it up to the UITextField, you will need to implement the UITextFieldDelegate and call your showPopover code from the textFieldDidBeginEditing method.
The rect you use should be the rect of the TextField.