I am hiding a UIButton underneath a UITextField. Normally, the UIButton responds just find. However, when I set it to hidden (or when I set alpha to 0), it stops working.
For context, I am including a hidden button under a UITextField because the clickable area to edit the textfield is small--I'd like the user to be able to click anywhere in the neighborhood of the uitextfield in order to make the text field become the first responder. Thus, the code for the button is:
- (IBAction)enterTextField:(id)sender {
[nameTextField becomeFirstResponder];
NSLog(#"Pressed");
}
However, this code does not get called when the button is hidden. Otherwise, it does get called.
Make it a custom button with UIButtonTypeCustom or set the background to clearColor.
Related
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.
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.
I have a UItextField in a UIScrollView. I assigned an inputView (a picker) on my UITextField but it doesn't work. When I click on my textfield, I get the keyboard instead of a picker. When I delete the UIScrollView it works well (I get the picker). Do you have any ideas? Thanks.
Edit (more clear): I have a UItextField in a UIScrollView. I call a method that shows a picker. But the method is never called when my textfield is in a scrollview and I get the keyboard. When I delete the UIScrollView, my method (show picker) is called and I get my picker.
In case you are already using the textfield delegate, try ...
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[self openCustomPicker:self]; // Call your IBAction method
return NO; // Hide both keyboard and blinking cursor.
}
to prevent the UITextField from showing the keyboard.
I have a set of UIButtons (defined in a xib) who have labels that need to be updated periodically. In the ViewDidLoad method of the view controller of those buttons' superview, I have an update method that does, for each button:
button.titleLabel.text = #"Relevant Text";
[button setNeedsDisplay];
and when you tap a button, another method runs which pops up a UIAlertView, which in turn calls back a method on the view controller which does much the same thing as the initial text setting method:
button.titleLabel.text = #"New Text";
[button setNeedsDisplay];
however, this code simply isn't working, the button label's text doesn't get updated in either method, it remains a blank white button. In the xib I don't define any text on the buttons - there's no point, the button text doesn't make sense unless it's set at runtime. Anyway, on a lark, I decided to set the text of one of the buttons to "test test test".
Now, when I tap that particular button, it pops up the UIAlertView but in the background changes the text of the button to "test test test test". And this time, the UIAlertView callback does what I expect it to and sets the text for only that button. When I hit it again, the text goes back to "test test test test" until I dismiss the UIAlertView, which again will run the callback method and set the button text to whatever the method should.
I have no idea what's going on here, or why setting the text initially in the xib has any relation to whether or not I can set that text later programatically. Obviously this isn't the behavior I want, I want to know how to for sure set the text on the buttons.
Edit: SVD's advice about setTitle:ForState: solved my problem, thanks. I'm still curious though as to why the title label set in the .xib shows up, but only when I have a UIAlertView pop up.
You may need to use [setTitle: forState:] to set the button title for normal and highlighted (or selected) state.
(And do make sure the button is connected to the outlet, as jtbandes points out).
I have a set of UIButtons (defined in a xib) who have labels that need to be updated periodically. In the ViewDidLoad method of the view controller of those buttons' superview, I have an update method that does, for each button:
button.titleLabel.text = #"Relevant Text";
[button setNeedsDisplay];
and when you tap a button, another method runs which pops up a UIAlertView, which in turn calls back a method on the view controller which does much the same thing as the initial text setting method:
button.titleLabel.text = #"New Text";
[button setNeedsDisplay];
however, this code simply isn't working, the button label's text doesn't get updated in either method, it remains a blank white button. In the xib I don't define any text on the buttons - there's no point, the button text doesn't make sense unless it's set at runtime. Anyway, on a lark, I decided to set the text of one of the buttons to "test test test".
Now, when I tap that particular button, it pops up the UIAlertView but in the background changes the text of the button to "test test test test". And this time, the UIAlertView callback does what I expect it to and sets the text for only that button. When I hit it again, the text goes back to "test test test test" until I dismiss the UIAlertView, which again will run the callback method and set the button text to whatever the method should.
I have no idea what's going on here, or why setting the text initially in the xib has any relation to whether or not I can set that text later programatically. Obviously this isn't the behavior I want, I want to know how to for sure set the text on the buttons.
Edit: SVD's advice about setTitle:ForState: solved my problem, thanks. I'm still curious though as to why the title label set in the .xib shows up, but only when I have a UIAlertView pop up.
You may need to use [setTitle: forState:] to set the button title for normal and highlighted (or selected) state.
(And do make sure the button is connected to the outlet, as jtbandes points out).