Creating a new keyboard button for iPhone - Bug in InputAccessoryView and InputView - iphone

I create a 2 UITextView in my program. They will have to do this:
TextView1 - Will have a new InputView
TextView2 - Will be a normal numeric keyboard with a new button
Because the numeric keyboard of iPhone have a empty button in left of zero. So, I can put a UIView there to simulate a new keyboard. So, I created a UIView with a UIToolbar and this button and set in TextView with a simple
[textView setInputAccessoryView:myView];
To catch a click inside this view is a little more complex. I have to subclass the principalClassName in main.m
int retVal = UIApplicationMain(argc, argv, MyPrincialClass ,MyDelegateClass);
Then create this class with
#interface MyPrincialClass : UIApplication
- (void)sendEvent:(UIEvent *)anEvent;
#end
#implementation MyPrincialClass
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
NSSet *touches = [event allTouches];
UITouch *touch = touches.anyObject;
[[NSNotificationCenter defaultCenter] postNotificationName:#"click" object:(id)touch];
}
#end
Now is only listen this Notification and check if this click is in correct area.
Because I have a UINavegationBar, I have to go to "Next" and "Previous" TextView. OK, this is only run
[textView1 resignFirstResponder];
[textView2 becomeFirstResponder];
If all textView have the same inputView (the keyboard) than the button work normaly. But... Because one of this textView have another inputView, than my problem start.
If I first click in a normal UITextView with a button, than the button is show correct like this. The red square is above the keyboard, so it work.
If the first click is in the UITextView with a customized inputView, the button is show correct again
but now, If navegate with the tool bar (with is a simple resignFirstResponder and becomeFirstResponder) the button will be show under the keyboard
In resume... All the problem in only because I use a custom inputview. If I only use the keyboard, I will not have any problem.
To solve this, is only put the UIView of custom button above the keyboard. I try to get the main UIWindows and send the message:
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:myview];
But not work. Any idea to solve this bug??

I Hope i understand you correctly, and i would suggest you to manage Z Position of the button. So that It can appear above all the component. For easy doing i suggest you the following open source,Manage Z Order of Views.
Hope this will help you, if not please let me know .
Cheers,
Arun.

I fix it. The idea was find the UIView of keyboard and add the button like a subview. This was the codes:
- (void)keyboardDidShow {
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(UIView* potentialKeyboard in tempWindow.subviews) {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
if([[potentialKeyboard description] hasPrefix:#"<UIPeripheralHost"] == YES) {
keyboard = potentialKeyboard;
} else {
if([[potentialKeyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
keyboard = potentialKeyboard;
}
}
}
}
[keyboard addSubview:key];
[keyboard bringSubviewToFront:key];
}

Related

Hide keyboard on ViewWillAppear

i have a screen having navigation controller and text field. when i move next and come back i want the keyboard should be hidden in first screen. I am hiding keyboard like on textfield event.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
But how to do that in View related events so that whenever my view appears keyboard is hidden..
Pls guide/Help.
thanks in adv.
I think this is also a good way to remove keyboard with in iOS App if your UITextView or UITextField not connected through the IBOutlet.
If you want to Hide Keyboard with UIViewController LifeCycle Events like with viewWillAppear or etc. Follow this
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self view] endEditing:YES];
}
Otherwise if you object connected using IBOutLet this code will work fine as you describe too.
[yourTextField resignFirstResponder];
Add this code to your ViewWillAppear :
for(id obj in self.view.subviews)
{
if([obj isKindOfClass:[UITextField class]])
{
[obj resignFirstResponder];
}
}
This would take in all the textfields in that particular view here it is the whole view and add the code you had written previously for removing the keyboard.
A good habit is to write this code in your screen's -viewWillDisappear. So, when you navigate from one screen to another at that time it will remove the keyboard from that screen.
- (void)viewWillDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[super viewWillDisappear:animated];
}
For multiple textFields, it is better to use -endEditing for that particular view instead of -resignFirstResponder for any single textField. Take a look at my Answer.
//This is for Swift
override func viewWillAppear(animated: Bool)
{
self.view.endEditing(true)
}
The thing that you are doing wrong is , when you are moving back previous controller to the current controller , the keyboard is up due to the selected textfield of previous controller .
And in the current controller the code:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self view] endEditing:YES];
}
It will not work as no textfield is selected at this controller. So what you need to do is write the same code in the previous controller viewWillDisappear Method it will surely resolve your Problem .
- (void)viewWillDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[super viewWillDisappear:animated];
}

UITextField - resignFirstResponder Query

I have an application which has a couple of UITextField present to allow my user to enter their age, and another numerical value. Ideally, I want the keyboard to bring up the numeric keypad when the TextField is being edited. At present I have it set to Numer and Punctuation merely to make use of the 'Done' button to dismiss the keyboard as the Numeric pad does not have a done button.
In an attempt to use the Numeric keypad, I have tried to set it to dismiss by tapping the background of my main view.
-(IBAction)backgroundTapped:(id)sender;
I created the above action in my header file.
-(IBAction)backgroundTapped:(id)sender {
[ageEntry resignFirstResponder];
}
I have expanded on the above method in my implementation file to tell the ageEntry TextField to resignFirstResponder. I have also changed my main view to a UIControl class and connected the buttonTapped action to the relevant alert through Interface Builder. Yet when I touch the background nothing happens.
Any ideas?
Just detect the touch in your viewController's view using the method
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[urAgeField resignFirstResponder];
[urOtherField resignFirstResponder];
}
and resign the keyboard in this method
A much easier method is to add a inputAccessoryView to your text field. This input accessory view can be a UIToolbar with a single UITabBarButton for your Done button.
Much less of a hack, and will look like the accessory view that is used in for example Safari to dismiss the keyboard.
i had a similar problem. here is the solution..
EDITED
add
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(tap:)];
tap.numberOfTapsRequired = 1;
[self addGestureRecognizer:tap];
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
[ageEntry resignFirstResponder];
}

How to cancel the keyboard in UISearchbar?

I'm using UISearchBar in my application and it serves as both an edit field as well as a search. So when I want to disappear the keyboard I have to use cancel button in UISearchBar but I can't have that cancel button on screen, so how could T make keyboard disappear when not used without using cancel button. Please help me as i'm new to iPhone application development.
Thanks in advance!
Use this:
[UISearchBar resignFirstResponder];
Just replace the word UISearchBar with the name of the object you have created.
Are you looking for ways you can dismiss the keyboard or how to actually do that programmatically? If programmatically, then [UISearchBar resignFirstResponder]. If you are looking for a possible way for the user to achieve that you can either make the return button on the keyboard resign its first responder status when pressed, or attach a UIGestureRecognizer to your view and set it up so that when the user clicks outside the keyboard, this keyboard goes away.
simply all you need to do is to get UITextfield control from the UISearchbar and then set UITextfield's delegate to whatever delegate that will perform -(void) textFieldShouldReturn:(UITextField *)textField
-(void)viewDidLoad{
UIView * subView;
NSArray * subViews = [searchbar subviews];
for(subView in subViews)
{
if( [subView isKindOfClass:[UITextField class]] )
{
((UITextField*)subView).delegate=self;
((UITextField*)subView).returnKeyType=UIReturnKeyDone;
break;
}
}
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return TRUE;
}

How to set Custom keyboard specific to only a UItextfield

How to set Custom keyboard specific to only a UITextField? When I am changing using this method, all the keyboards in my application are changed to this new custom keyboard. I added:
[[NSNotificationCenter defaultCenter] addObserver:self.view
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
in a UIViewController. But after going to that UIView, keyboards in other UIViewControllers also look like new custom keyboard. How can i limit the custom keyboard to only one UIView? Please help me. Thanks in advance.
UITextField* textField;
UIView* customKeyboard;
textField.inputView = customKeyboard;
Similar thread: iPad custom Keyboard GUI
If you subclassed UITextView (as that tutorial shows), then all instances of that subclass will use the toolbar with a dismiss button.
If you don't want the toolbar, then don't use the subclass, just use the original UITextView.
You can try checking for the textfield that you want on the textFieldShouldBeginEditing like so:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == YOUR_DESIRED_TEXTFIELD) {
[self openCustomKeyboard];
}
return YES;
}
My problem was once am loading custom keyboard, it remains everywhere in other UIviews of application. So i checked existence of UIToolbar in other UIkeyboard subviews and removed . Now its working fine..
for(UIView* keyboardToolbar in [keyboard subviews]){
if([[keyboardToolbar description] hasPrefix:#"<UIToolbar"] == YES)
{
[keyboardToolbar removeFromSuperview];
}
}

UITextView has no events

I am developing an iPhone application which requires a multiline text field (UITextView) to capture some text.
When the user touches inside the textView it becomes firstResponder and displays the keyboard. What I really need it to do is remove the keyboard when the user is finished. Normally with a text field the return/done button press would signal the end of typing and I would use the delegate to resign first responder. However with a multiline textview I want the user to be able to add a new line so that is not possible.
My next option would be to resign first responder if there is a touch up outside of the text view. The problem here is that there are no events declared on UITextView which I can see in interface builder.
How can I create a multiline text field in an iPhone app which will release first responder at a sensible time when the user is done with it?
You can use a DONE button on the navigation bar:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneAction:)];
}
to dismiss the keyboard, handle the event with something like:
- (void) doneAction: (id) sender{ [textView resignFirstResponder]; }
(remember .h file declarations)
I'm guessing you are lamenting the "missing" Done button on the keyboard which is return on a multi line UItextView, correct me if i'm wrong.
The obvious approach seems to have another button on your interface that resigns first responder.
I don't think some clever code that hides the keyboard upon some event would be very intuitive to use.
The Apple Notes application uses its top right done button to resign first responder, an approach like this seems sensible.
//If user touches outside of the keypad, then the keypad will go away
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (touch.tapCount >= 1) {
[ZLabel resignFirstResponder];
}
}
You can create an invisible button that covers all screen and than add a method to it. I think sth like this will work.
- (IBAction)backgroundClick:(id)sender{
[textView resignFirstResponder];
}
If you are completely set on having the 'done' key on the keyboard, the method I use is check the last character in the UITextView when the contents changes. If the last character is a new line, then the user has hit the done button. I would second Neil's view that there should be another button, but sometimes the customer gets what the customer wants.
Obviously you will have to set the delegate for the UITextView to point to the class in which this method lives. The - (void)textViewDidChange:(UITextView *)inTextView method is part of the UITextViewDelegate protocol.
- (void)textViewDidChange:(UITextView *)inTextView {
NSString *text = inTextView.text;
if ([text length] > 0 && [text characterAtIndex:[text length] -1] == '\n') {
message = [text substringToIndex:[text length] -1];
[delegate messageEdited];
[self removeFromSuperview];
}
}
(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
[txtView resignFirstResponder];
return YES;
}