NSTextField is first responder but I still must click inside the text box before typing - objective-c

My ultimate goal is to have an NSTextField selected by default allowing the user to start typing without clicking on the text field first.
I have a view controlled by a NSViewController. The view contains several text fields. The NSView and NSWindow are both custom subclasses. The text field is not subclassed. Just a standard NSTextField.
Inside awakeFromNIB for the view controller I have the code:
[[[NSApplication sharedApplication] mainWindow] makeFirstResponder:firstBox];
NSLog(#"%#",NSStringFromClass([[[[NSApplication sharedApplication] mainWindow] firstResponder] class]));
The text field gets a focus ring around it, and the NSLog prints that the first responder is an NSTextField but I still have to click inside the text field before I can begin typing.
What could cause the field to be the first responder but not editable? Is there a better method I should be calling makeFirstResponder from?

I found a potentially useful hint on CocoaDev.com, try doing this:
[[[NSApplication sharedApplication] mainWindow]
performSelector: #selector(makeFirstResponder:)
withObject: firstBox
afterDelay:0.0];

Related

NSTextField not noticing lost focus on NSWindow close

I have several NSTextField that are used on a dialog created as an NSWindow and which is displayed via:
[NSApp runModalForWindow:dialog]
My problem is that if a user clicks in the NSTextField, edits the value and then clicks the dialogs DONE button which closes the dialog via:
[NSApp stopModal]
The NSTextField doesn't get any of the delegate methods indicating editing will end or has ended and the value is not persisted.
I would rather not persist the values continuously in:
controlTextDidChange:aNotification
I'm not clear why if the NSTextField has firstResponder status given that it is being edited, and then loses it, why it doesn't get any delegate methods. Is there some other way to detect this.
What fixed this was changing this:
[self resignFirstResponder];
to this:
[self makeFirstResponder:nil];
By doing that the text field on the modal window that currently had focus got the message. I'm not sure why resignFirstResponder doesn't work but setting it to nil doe, but there you have it.

Can't type in UITextField if presentViewController while editing

I have a ConfigureViewController that contains some UIButtons and a UITextField * MyTextField. Each of the buttons, when pressed, brings up a dialog-style viewcontroller using presentViewController:animated:completion:. However, if I tap one of those buttons while editing the text field, when i close the dialog and return to the original screen, i am unable to return focus to or type in the text field.
This is the method that is invoked when the button is tapped.
-(void)AdvancedInfoButtonPressed :(id)sender
{
AdvancedInfoPopViewController *myAdvancedInfoViewController = [[AdvancedInfoPopViewController alloc] init];
[myAdvancedInfoViewController setDelegateAndDevice :self :Current_Device];
myAdvancedInfoViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController :myAdvancedInfoViewController animated :NO completion :nil];
}
Without explicitly removing focus from MyTextField, presenting the AdvancedInfoViewController does dismiss the keyboard automatically.
I suspect the problem is that MyTextField still thinks it has focus (even though the keyboard and blinking cursor have disappeared) and so does not allow itself to become the first responder again. Along these lines, I have found that if i add [MyTextField resignFirstResponder] before presenting the dialog viewcontroller, the problem goes away.
However, this does not seem like a very good solution because it means having to remember to resign this textfield (or any other text fields) as the first responder in several places (leading to code that is difficult to maintain). My question is: are there any events i can hook into either when ConfigureViewController is about to be partially obscured by AdvancedInfoViewController (or when AdvancedInfoViewController is dismissed and focus is returned to the ConfigureViewController) in which i can add some logic to clean up MyTextField's firstResponder status?
I've tried viewWillDisappear and viewWillAppear but they are never called on the ConfigureViewController.
I've also tried adding textFieldDidEndEnding to the text field's delegate but, despite it being called, it did not fix the problem.
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[MyTextField resignFirstResponder];
}
You can use [self.view endEditing:YES] to resign all first responders in the case you are presenting myAdvancedInfoViewController.
To return focus to the textField after this event occurs you will need to keep track of which textField was active at the time myAdvancedInfoViewController was presented. When the myAdvancedInfoViewController is dismissed call UITextField's becomeFirstResponder method for the appropriate text field.

UIVIew endEditing:YES doesnt hide the keyboard

I have a UIVIew which is a subview and it contains several UITextFields. One of these textfields (which is for DATE) should not be editable using the keyboard, instead of this I use a PopOver with a Datepicker inside.
I run a method when the UIControlEventEditingDidBegin is reached. This method calls the resignFirstResponder on the DateTextField.
Everything works fine if the DateTextField is the first field to edit, but when another textField is edited and of course shows the keyboard and then try to edit the DateField, the keyboard doesn't hide and everything goes normal but with the Keyboard doing anything.
I have tried to call the method endEditing:YES before the resignFirstResponder but it doesn't work. I have tried to run the endEditing:YES and resignFirstResponder on the didEndEditing text field method but theres no way to get that keyboard out.
here is my method:
- (void)showDatePopOver:(id)sender{
[self.view endEditing:YES];
UITextField *textField = (UITextField *)sender;
[sender resignFirstResponder]; // hide keyboard
/** POP OVER LINES**/
}
You should use the textFieldShouldBeginEditing: delegate method instead of resigning first responder in didBeginEditing:
This will allow editing on ALL BUT the dateTextField text field:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return (![textField isEqual:dateTextField]);
}
You should specify that your view controller is a text view delegate as well like so (in the interface declaration [.h file]):
#interface MyViewController : UIViewController <UITextFieldDelegate>

Custom UIView and becomeFirstResponder

I have a custom UIView that implements the UIKeyInput protocol and has
- (BOOL) canBecomeFirstResponder{
return YES;
}
defined in the subclass. When calling:
[customView becomeFirstResponder];
NSLog(#"is first? %i",[customView isFirstResponder]);
during a button click, it returns false, even though canBecomeFirstResponder is properly set and all of the UIKeyInput protocol functions are implemented. What other things could be blocking this view from becoming the first responder? It lives inside of a scrollView and another custom view if that helps.
Update:
I checked to see what the current first responder was with:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:#selector(firstResponder)];
and surprisingly firstResponder was nil. So nothing seems to be hogging the events.
Did you override becomeFirstResponder?
Subclasses can override this method to update state or perform some
action such as highlighting the selection.
Followup:
Subclasses can override this method to update state or
perform some action such as highlighting the selection.
A responder object only becomes the first responder if the current
responder can resign first-responder status (canResignFirstResponder)
and the new responder can become first responder.
You may call this method to make a responder object such as a view the
first responder. However, you should only call it on that view if it
is part of a view hierarchy. If the view’s window property holds a
UIWindow object, it has been installed in a view hierarchy; if it
returns nil, the view is detached from any hierarchy.
Did you verify you meet all of the above conditions?

Show keyboard with a UIPopover

How can I show the keyboard when my popover shows up?
The popover is UIViewController that I call from a popoverController.
The popover has an UITextField and when the popover is displayed, the keyboard need to show up too and the cursor go to the UITextfield.
I tried to put the becomeFirstResponder under viewDidLoad or viewWillLoad, and not work.
[userValue becomeFirstResponder];
What I miss?
That's all folks. Thanks.
You need to make the textField the first responder, not the popover itself. Just because you make an object the first responder, doesn't mean it will show the keyboard. It needs to be an object with text entry properties, like a UITextField, to display the keyboard.
- (void)viewDidAppear:(BOOL)animated{
[_textField becomeFirstResponder];
[super viewDidAppear:animated];
}
You can call the method above if you want that particular textField to be the first responder, with keyboard, each time the popover is displayed. Remember, this method is called AFTER the popover is loaded.
Hope this helps.
Assign the first responder in the viewWillAppear method.
i think u didn't set the textfield delegates to self and trying putting breakpoints and check what is happening ,is it even going to textfield delegates or not.