I have a NSTextField on the view of an NSCollectionViewItem.
When you click an NSCollectionViewItem the item is selected.
When you click the NSTextField it gains focus, but the NSCollectionViewItem which is behind the text field does not get selected.
I want to change this last behaviour so the text field gets focus and the view item also gets selected.
What's the best way to do this?
I believe you would have to subclass NSTextField and override mouseDown to pass the event to the nextResponder (which should be set to your collection view)
I also have an NSCollectionViewItem that contains an NSTextField. I'm trying to recreate the basic look and feel of the text label of an Icon in the Finder. I haven't finished it yet, but what I have so far seems to answer this question.
The key is to have the text field start out as NOT selectable. A mouse click on the text field will be ignored by the text field and will select the collection view item. Then in the collection view item's setSelection method, when it is being selected, set the text field as editable. The next mouse click on the text field will give it focus. Then when the collection view item is being unselected, set the text field back to not selectable and wait for the collection view item to be selected again.
-(void)awakeFromNib
{
[self.textField setSelectable:NO];
}
-(void)setSelected:(BOOL)selected
{
[super setSelected:selected];
if (self.selected)
{
[self.textField setEditable:YES];
}
else
{
[self.textField setSelectable:NO];
}
}
This answers the above question, but obviously, more is needed for a complete solution.
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’m using a regular (not subclassed) NSTableCellView in a view-based table view. It has the initial image and text field views. I added an NSStepper to the view.
The text field is bound to tableCellView.objectValue.quantity.
The stepper’s value is bound to tableCellView.objectValue.quantity too.
The problem is that when running the app, when I click the stepper it doesn’t seem to get the mouse event, neither arrow gets highlighted, the value is not incremented or decremented.
If I set the double action of the table view it gets triggered if I double-click the stepper as if it was transparent.
What am I missing?
Thanks!
You should look at the documentation but easiest is that you need to subclass NSTableView and override this method to validate the proposed first responder. As the document states NSTableViews disallow some controls to be used unless the row is first selected. Even then it still may discard some.
- (BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event {
return YES;
}
Further to the correct answer from Robert Payne, with Swift you could add an extension to NSTableView and not subclass it.
extension NSTableView {
override public func validateProposedFirstResponder(responder: NSResponder, forEvent event: NSEvent?) -> Bool {
return true
}
}
And I'd like to emphasis that it's the NSTableView not the NSTableViewCell.
At the moment, I trigger a method on 'Did End On Exit' in my app (I'm aware that this may not be the greatest way of doing it but I'm very new to Objective C and Xcode for that matter and I'm simply doing what feels comfortable to me).
This method resigns the firstResponder from the current text field and applies it to a later text field.
The problem I'm facing is that the keyboard covers the next text field so that the use has no idea where the focus is and therefore what they are required to type.
How do I get it so that my keyboard shifts down and actually shows the text box that is currently active? Making something the firstResponder simply doesn't do what I want it to, unless there's part of the implementation I'm missing.
Here's my simple method:
- (IBAction)firstNameNext:(id)sender {
[firstNameTextField resignFirstResponder];
[surnameTextField becomeFirstResponder];
}
Any advice would be super.
Add UIScrollView in your main view then all contents as subview to UIScrollView
Now when specific UITextField needs to be able to visible in view use its delegate like this:
Note: add UITextFieldDelegate in .h file like this
#interface yourViewController : UIViewController<UITextFieldDelegate>
Also bind with File's Owner
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
{
if(textField == yourSpecficTextField) //one u want move upwards
{
yourScrollView.contentOffset = CGPointMake(0,200); //required offset
}
... //provide contentOffSet those who needed
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
yourScrollView.contentOffset = CGPointMake(0,0); //make UIScrollView as it was before
}
If you have keyboard input fields that will be covered by the virtual keyboard, then you need to move those fields out from under the virtual keyboard.
The normal way to do this is to have the controller's view be a scrollable view like UIScrollView. Moving Content That Is Located Under the Keyboard gives a very robust way of adjusting your scroll view and ensuring the required field shows.
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];