Can't type in UITextField if presentViewController while editing - objective-c

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.

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.

How can I make my NSTextField NOT highlight its text when the application starts?

When my application launches, the first NSTextField is being selected like this:
I can edit the NSTextField fine, but when I press enter to end the editing, the text becomes selected again, and the editing does not end.
I followed the Apple tutorial here, and I had the same problem with the text field being perpetually highlighted.
How do I stop this? I would like it so the text field is not the first responder of the app so it's not edited right away, and when it is being edited, clicking outside of the text field will end it. I'm not sure where to put the [[textField window]makeFirstResponder:nil] to stop the editing in the latter case.
I'm running Yosemite 10.10.2.
Your text field is selecting the text, due to the default implementation of becomeFirstResponder in NSTextField.
To prevent selection, subclass NSTextField, and override becomeFirstResponder to deselect any text:
- (BOOL) becomeFirstResponder
{
BOOL responderStatus = [super becomeFirstResponder];
NSRange selectionRange = [[self currentEditor] selectedRange];
[[self currentEditor] setSelectedRange:NSMakeRange(selectionRange.length,0)];
return responderStatus;
}
The resulting behavior is that the field does not select the text when it gets the focus.
To make nothing the first responder, call makeFirstResponder:nil after your application finishes launching. I like to subclass NSObject to define doInitWithContentView:(NSView *)contentView, and call it from my NSApplicationDelegate. In the code below, _window is an IBOutlet:
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[_menuController doInitWithContentView:_window.contentView];
}
The reason your field is getting focus when the application starts is because the window automatically gives focus to the first control. It determines what is considered first, by scanning left to right, top down (it scans left to right first, since a text field placed at the top right will still get focused). One caveat is that if the window is restorable, and you terminate the application from within Xcode, then whatever field was last focused will retain the focus state from the last execution.
I am using IB, there's a property on NSTextField called Refuses First Responder. Ticking that will prevent the highlighting of the text field immediately after the window is presented. There's some more detailed info about Refuses First Responder in this question.
No need to subclass. Simply set refusesFirstResponder = YES;
NSTextField *textField = [NSTextField new];
textField.refusesFirstResponder = YES;
That's it! Do that and it won't highlight the text in the field.

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

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];

UITextView won't resignFirstResponder so another can becomeFirstResponder

I have a toolbar in my UITextfields' inputAccessoryView. If the 'next' button is hit it makes the next textfield in an orderedSet of all my textfields become the first responder. THAT works perfectly.
BUT I can't get the 'previous' textfield to becomeFirstResponder.
I've checked in the console and the textfield does call textFieldShouldBeginEditing and I am returning YES but it never calls textFieldDidBeginEditing and the textfield that should resignFirstResponder never calls textFieldShouldEndEditing.
So the textfield is getting the message to becomeFirstResponder but doesn't.
- (IBAction)keyboardBarButtonDidTouch:(UIBarButtonItem *)sender
{
if (sender==self.previousBarButton&&self.activeTextFieldArrayIndex.intValue>0)
{
[(UITextField *)[self.textfields objectAtIndex:(self.activeTextFieldArrayIndex.intValue-1)] becomeFirstResponder];
}
if (sender==self.nextBarButton&&self.activeTextFieldArrayIndex.intValue<(self.textfields.count-1))
{
[(UITextField *)[self.textfields objectAtIndex:(self.activeTextFieldArrayIndex.intValue+1)] becomeFirstResponder];
}
if (sender==self.doneBarButton)
{
[self.activeTextField resignFirstResponder];
}
}
The weirdest thing is that if I force the textfield to resignFirstResponder by some action that just does that, the 'previous' textfield suddenly becomesFirstResponder. Like it was being added to a list of responders and it became its turn....
And as is often the case when strange things happen, it was unrelated to becoming first responder. I was accidentally changing my activeTextfield pointer to nil in the middle of a bunch of logic by way of the textfield delegate. ^o^
Disregard!
1) Try making your code less error prone.
instead of this
if(sender==self.previousBarButton&&self.activeTextFieldArrayIndex.intValue>0)
do this
if ((sender==self.previousBarButton) && (self.activeTextFieldArrayIndex.intValue>0))
2) use textfield.tag property and set unique tags for these text fields. and do your stuff about become/resign first reponders by using
(uitextfield *)field[self viewWithTag: uniqueTag];

Change default insertTab: action in NSSearchfield

I have a view with a nssearchfield a nstableview and a nsmatrix with three radiobuttons. Using delegates i change the selected radiobutton when the searchfield is the firstresponder and the user press tab, that works perfectly but what i want is that the searchfield don't loose the firstresponder when the user press tab
You can sub class NSSearchField and add this function
- (BOOL)resignFirstResponder {
return NO;
}
It will refuse to relinquish first responder status.
Another way is catch the windowDidUpdate notification. These are sent whenever anything changes, including change of focus, so you can check for the firstResponder and make it become first responder again.
[searchField becomeFirstResponder];