In my application, I'm forcefully showing/hiding keyboard by making textview becomefirstresponder and resignfirstresponder and also setting textview editable YES and NO respectively.
But after hiding keyboard if I tap on textview, the keyboard doesn't show up. I'm setting textview delegate to self. And the delegate method is firing up the first time but not after that.
EDIT: I'm using the following code which I am writing for a custom button-tap and checking flags to check keyboard is in hidden state or otherwise:
switch(rotationFlag)
{
case 0:
{
[self hideKeyboard];
rotationFlag = 1;
break;
}
case 1:
{
[self showKeyboard];
rotationFlag = 0;
break;
}
}
-(void)hideKeyboard{
[txtVwForPosts setEditable:FALSE];
[txtVwForPosts resignFirstResponder];
}
-(void)showKeyboard{
[txtVwForPosts setEditable:TRUE];
[txtVwForPosts becomeFirstResponder];
}
What is it that I'm doing wrong?
Can anybody please help?
Thanx in advance.
I'm not sure whats wrong with your code but following is a code which i wrote for same purpose:
-(IBAction)hideShowKeyboard:(id)sender
{
if([tv isFirstResponder])
{
[tv resignFirstResponder];
}
else
{
[tv becomeFirstResponder];
}
}
THis was the action for the button. and tv is the TextView outlet. But this view doesn't detect tap on the textview after the keyboard is hidden. If you want to detect taps just avoid setting the editable property to NO.
switch(rotationFlag)
{
case 0:
{
[self hideKeyboard];
rotationFlag = 1;
break;
}
case 1:
{
[self showKeyboard];
rotationFlag = 0;
break;
}
}
-(void)hideKeyboard
{
[txtVwForPosts resignFirstResponder];
}
-(void)showKeyboard
{
[txtVwForPosts becomeFirstResponder];
}
Related
I am creating a "sign in" and "create account" form for my iOS app. I successfully implemented the scrolling up of the UITextField when it is hidden. However, now that I implemented the "next" button the "UIKeyboardDidShowNotification" is not called because the keyboard is never dismissed. I need the keyboardWasShow method called so I can check if the active UITextField is hidden or not.
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
CGPoint pointInSuperview = [self.view convertPoint:self.activeField.frame.origin fromView:self.scrollView];
aRect.size.height -= kbSize.height;
//added 10 to y axis because tip of origin was outside of keyboard
pointInSuperview.y +=20;
if (!CGRectContainsPoint(aRect, pointInSuperview)) {
CGPoint scrollPoint = CGPointMake(0.0, pointInSuperview.y - (kbSize.height -15));
NSLog(#"it is not in the rect");
[self.scrollView setContentOffset:scrollPoint animated:YES];
}
}
and I have an observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
and after I implemented my Next button (see below) the keyboardWasShown method is not called so it never checks if the active UITextField is hidden.
//functionality for next action
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == self.emailAddress) {
[self.fullName becomeFirstResponder];
[self keyboardWasShown:(NSNotification*)UIKeyboardDidShowNotification];
}
else if (textField == self.fullName) {
[self.password becomeFirstResponder];
}
else if (textField == self.password) {
[self.confirmPassword becomeFirstResponder];
}
[textField resignFirstResponder];
return YES;
}
What would be the best approach to call keyboardWasShown when the user clicks the Next button? I tried making it a public method but I kept getting errors when I tried to call it manually.
One way to avoid this is to resign the responder prior to setting the next responder, which will ensure that the keyboardWasShown notification was called. For example, based on your code you could use the following:
...
else if (textField == self.fullName) {
[self.fullName resignFirstResponder];
[self.password becomeFirstResponder];
}
...
Whilst this might seem odd, it should be noted that the keyboard doesn't actually disappear/reappear.
You may want to look into this
If your fields arent in a table the same sort of logic can apply to other cases.
In one UIViewController, I have a UISegmentedControl.
When I select segmented control.selectedindex==0, it will show a textfield.
When I select segmentedcontrol.selectedindex==1, it will show another segmented control instead of textfield.
How can I do that?
Wouldn't you just have 2 segmented controls, but one of them hidden.
When selectedindex==1 on the first one, then unhide the second one.
-(IBAction)yourSegmentControl:(id)sender{
switch ((((UISegmentedControl *)sender).selectedSegmentIndex)) {
case 0:
{
anothersegment.hide = YES;
yourTextfield.hide = NO;
break;
}
case 1:
{
anothersegment.hide = NO;
yourTextfield.hide = YES;
break;
}
default:
break;
}
}
Make sure that in your viewDidLoad you initialize your textfield and secondsegmentcontrol
both to hide = YES;
I am trying to hide and display a UIView on BarButtonItem click. Priviously i also posted the question regarding same but didnt find any suitable answer. I created UIView manually in IB and just placed it in view so it must be shown as soon as view is loaded but i made it hidden in viewDidLoad method by writing
myvew.hidden = YES;
secondly, when i click BarButtonItem then i set
-(IBAction)mymethod
{
myview.hidden = NO;
}
so its diplaying view but when i again click on it it must hide.. how do i do it?
Put the following statement in your button action
myview.hidden = !myview.hidden ;
So your code must be like below.
-(IBAction)mymethod
{
myview.hidden = !myview.hidden ;
}
if (myview.hidden == YES)
{
myview.hidden = NO;
}
else
{
myview.hidden = YES;
}
Check if the view is already hidden and then show, and if not hidden then hide it.
You should do in this way
-(IBAction)mymethod
{
if( myview.hidden == NO ) myview.hidden = YES;
else myview.hidden = NO;
}
I have alert view having 2 buttons "OK" and "Cancel" and a textfield.
Now i want to disable "OK" button until user enter some text in textfield.
How can i do this?
thanks in advance
UPDATE 2: For Swift 5.1
<#your alert controller#>.addTextField {(tf) in
//... set your tf characteristics i.e .keyboardType here
NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification,
object: tf,
queue: OperationQueue.main) { _ in
//enable or disable the selected action depending on whether the textField text is empty
<#your alert controller#>.actions[0].isEnabled = !tf.text!.isEmpty
}
}
posting this to update the response since ios 5 :
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
UITextField *textField = [alertView textFieldAtIndex:0];
if ([textField.text length] == 0)
{
return NO;
}
return YES;
}
UPDATE:iOS 8 Since Apple have deprecated the UIAlertView in favour of the UIAlertController. There is no longer a delegate call to alertViewShouldEnableFirstOtherButton:
So instead you would set the buttons enabled property via the UITextFieldTextDidChangeNotification
Add a textView to the alert with
(void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler
[<#your alert#> addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.delegate = self;
textField.tag = 0; //set a tag to 0 though better to use a #define
}];
Then implement the delegate method
(void)textFieldDidBeginEditing:(UITextField *)textField
- (void)textFieldDidBeginEditing:(UITextField *)textField{
//in here we want to listen for the "UITextFieldTextDidChangeNotification"
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(textFieldHasText:)
name:UITextFieldTextDidChangeNotification
object:textField];
}
When the text in textField changes it will invoke a call to "textFieldHasText:" and pass along a NSNotification*
-(void)textFieldHasText:(NSNotification*)notification{
//inside the notification is the object property which is the textField
//we cast the object to a UITextField*
if([[(UITextField*)notification.object text] length] == 0){
//The UIAlertController has actions which are its buttons.
//You can get all the actions "buttons" from the `actions` array
//we have just one so its at index 0
[<#your alert#>.actions[0] setEnabled:NO];
}
else{
[<#your alert#>.actions[0] setEnabled:YES];
}
}
Don't forget to remove your observer when done
I wanted to extend the answer by Ryan Forsyth by adding this. If you add a Default styled UIAlertView, you can get an out of range exception if you try to access a textfield as none exist, so check your view style first.
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView*)alertView
{
if(alertView.alertViewStyle == UIAlertViewStyleLoginAndPasswordInput ||
alertView.alertViewStyle == UIAlertViewStylePlainTextInput ||
alertView.alertViewStyle == UIAlertViewStyleSecureTextInput)
{
NSString* text = [[alertView textFieldAtIndex:0] text];
return ([text length] > 0);
}
else if (alertView.alertViewStyle == UIAlertViewStyleDefault)
return true;
else
return false;
}
You can create two buttons for Ok and Cancel.Then add those two as sub views in the UIAlertView.Now by checking the text(text length) in the textfield,You can perform enable and disable actions.
Without knowing the context of your application, the following may not apply - but have you read the iOS Human Interface Guidelines? It sounds as though you may be better off finding an alternative to UIAlertView if this is something that's going to be displayed to the user often.
Not really related to your question, but do not modify default UIAlertView if you don't want your app to be rejected. If I'm not wrong, you're adding textfields to the alertview, don't you? Like a login view. You should create your own view.
So, regarding your question, create your view, set the buttons has disabled, and delegate the UITextFields. When
- (void)textFieldDidBeginEditing:(UITextField *)textField;
is called, enable those buttons.
I want to change the UITextInputTraits of a keyboard while it is in use....
My ideal code would look something like this:
- (IBAction)nameTextDidChange:(UITextField *)sender {
if ([sender.text isEqualToString:#""]) {
sender.returnKeyType = UIReturnKeyDone;
} else {
sender.returnKeyType = UIReturnKeySearch;
}
}
So... I have a different 'Return' button for an empty string as I do a string with some text in. The code I posted above doesn't work, the keyboard retains it's original text input traits.
Any ideas anyone, or is this never going to work no-matter how hard I try?
Cheers!
Nick.
Thanks to Deepak, this is the code I actually used:
if ([sender.text isEqualToString:#""]) {
sender.returnKeyType = UIReturnKeyDone;
[sender resignFirstResponder];
[sender becomeFirstResponder];
} else if (sender.returnKeyType == UIReturnKeyDone) {
NSString *cachedLetter = sender.text;
sender.returnKeyType = UIReturnKeySearch;
[sender resignFirstResponder];
[sender becomeFirstResponder];
sender.text = cachedLetter;
}
You can make this work by adding the following lines at the end of the method.
if ([textField.text isEqualToString:#""]) {
textField.returnKeyType = UIReturnKeyDone;
[textField resignFirstResponder];
[textField becomeFirstResponder];
} else if (textField.returnKeyType == UIReturnKeyDone) {
textField.returnKeyType = UIReturnKeySearch;
[textField resignFirstResponder];
[textField becomeFirstResponder];
}
This should work.
You basically flip it on and off so that the text input changes. The second if is to make sure you flip only if needed.
[textField reloadInputViews] seems to do the trick...
resignFirstResponder/becomeFirstResponder & reloadInputViews have some caveats. See stackoverflow.com/questions/5958427/…. These change the keyboard back to its initial state. So if the user had toggled to one of the other keyboard layouts (numbers, punctuation, etc), that state will get lost. I've never found a good solution.