I have a password field of type NSSecureTextField say passwordField and a NSButton. I have assigned return key as key equivalent for the button action triggering. After pressing the button I get user entered text as [passwordField stringValue] this will give the correct value only, when user press return key after entering his password but not when user clicks on the button through mouse. In the latter case it will give nil value. I have tried hard to find the problem but no use. If anybody knows what is going wrong, please help me.
Regards
ypk
EDIT: This is observed only in 10.5 and works fine on 10.6.
Try checking Continuous on the text field in Interface Builder.
Also make sure Action is set as Sent On End Editing.
I've had a similar problem. For me, it turned out that the focus was not correctly set on the text field. Calling [window makeFirstResponder: textfield] after a timeout of 0.5 seconds solved it.
I usually explicitly call [window makeFirstResponder:nil as one of the first lines in my button click events to ensure the Sent On End Editing event is called.
Related
I'm trying to remove focus from a UITextField and even though I resign it from being first responder, I'm still not able to have the cursor not focus on the text field.
I don't have any other input on the view to move the focus to and I don't want to create a dummy one either. What is a good workaround for this?
As per the documentation.
To dismiss the keyboard, send the resignFirstResponder message to the text field that is currently the first responder. Doing so causes the text field object to end the current editing session (with the delegate object’s consent) and hide the keyboard.
If you call resignFirstResponder on your textfield then it will end the editing session and the cursor wont be focussing on that textfield.
So please verify one more time whether resignFirstResponder is getting called on that textfield which you want to remove the focus.
Please try to set your current class as delegate of your UITextField. I think you forget to set the delegate that's why it's not working as you are expecting.
I have several panels that contain NSTextField controls bound to properties within the File's Owner object. If the user edits a field and then presses Tab, to move to the next field, it works as expected. However if the user doesn't press Tab and just presses the OK button, the new value is not set in the File's Owner object.
In order to workaround this I have set Updates Continuously in the binding, but this must be expensive (EDIT: or at least it's inelegant).
Is there a way to force the bind update when the OK button is pressed rather than using Updates Continuously?
You're right that you don't need to use the continuously updates value option.
If you're using bindings (which you are), then what you should be doing is calling the -commitEditing method of the NSController subclass that's managing the binding. You'd normally do this in your method that closes the sheet that you're displaying.
-commitEditing tells the controller to finish editing in the active control and commit the current edits to the bound object.
It's a good idea to call this whenever you are performing a persistence operation such as a save.
The solution to this is to 'end editing' in the action method that gets called by the OK button. As the pane is a subclass of NSWindowController, the NSWindow is easily accessible, however in your code you might have to get the NSWindow via a control you have bound to the controller; for example NSWindow *window = [_someControl window].
Below is the implementation of my okPressed action method.
In summary I believe this is a better solution to setting Updated Continuously in the bound controls.
- (IBAction)okPressed:(id)sender
{
NSWindow *window = [self window];
BOOL editingEnded = [window makeFirstResponder:window];
if (!editingEnded)
{
logwrn(#"Unable to end editing");
return;
}
if (_delegateRespondsToEditComplete)
{
[_delegate detailsEditComplete:&_mydetails];
}
}
Although this is really old, I absolutely disagree with the assumption that this question is based on.
Countinously updating the binding is absolutely not expensive. I guess you might think this updates the value continuously, understanding as "regularly based on some interval".
But this is not true. This just means it updates whenever you change the bound value. This means, when you type something in a textView, it would update as you write; this is what you'd want in this situation.
I have a NSSlider which updates the content of an NSTextField. So far so good. It works as long as the NSTextField isn't focused or gets edited by the user (typing or staying blank etc.).
What I'm trying to get working is to force the update of the NSTextField via code, no matter what the user is doing.
That's the code of the slider changed value event:
-(IBAction) sliderTempoMoved: (id)sender{
[soundEngine setTempo:[sender floatValue]];
[labelTempo setStringValue:[NSString stringWithFormat:#"%0.2f%",[sender floatValue]]];
NSLog(#"slideTempoMoved: %f",[sender floatValue]);
}
The setStringValue method works as long as the NSTextField doesn't get edited...
Any clues on this problem ??
Regards,
Alex
I don't know how much help this is, but I tried your code and the NSTextField gets updated whether or not it's currently being edited. Check your NSTextField properties against mine. Maybe something there is keeping it from being updated.
You could also try calling [labelTempo abortEditing] before the call to setStringValue.
I have an application, which open popover with NSTextField. The text field is not editable. Behavior for text field is set to Editable. I still can paste and copy text to this field but i can't edit it.
Anyone knows, what can be wrong?
Not sure if you still need the answer, but there may be some others still looking. I found a solution on apple developer forums. Quoting the original author:
The main problem is the way keyboard events works. Although the NSTextField (and all its superviews) receives keyboard events, it doesn't make any action. That happens because the view where the popover is atached, is in a window which can't become a key window. You can't access that window in any way, at least I couldn't. So the solution is override the method canBecomeKeyWindow for every NSWindow in our application using a category.
NSWindow+canBecomeKeyWindow.h
#interface NSWindow (canBecomeKeyWindow)
#end
NSWindow+canBecomeKeyWindow.m
#implementation NSWindow (canBecomeKeyWindow)
//This is to fix a bug with 10.7 where an NSPopover with a text field cannot be edited if its parent window won't become key
//The pragma statements disable the corresponding warning for overriding an already-implemented method
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (BOOL)canBecomeKeyWindow
{
return YES;
}
#pragma clang diagnostic pop
#end
That makes the popover fully resposive. If you need another window which must respond NO to canBecomeKeyWindow, you can always make a subclass.
I struggled with this for a while as well, until I realized it was a bug.
However, instead of relying on an isActive state of a NSStatusItem view, I find it much more reliable to use the isShown property of the NSPopover you have implemented.
In my code, I have a NSPopover in a NSViewController:
- (BOOL)canBecomeKeyWindow
{
if([self class]==NSClassFromString(#"NSStatusBarWindow"))
{
NSPopover *mainPopover = [[((AppDelegate*)[NSApp delegate]) mainViewController] mainPopover];
if(![mainPopover isShown])
return NO;
}
return YES;
}
Balazs Toth's answer works, but if you're attaching the popover to NSStatusItem.view the status item becomes unresponsive - requiring two clicks to focus.
What i found when working with this solution is that when NSStatusItem becomes unresponsive, you can easily override this behavior like this
- (BOOL)canBecomeKeyWindow {
if([self class]==NSClassFromString(#"NSStatusBarWindow")) {
CBStatusBarView* view = [((CBAppDelegate*)[NSApp delegate]) statusItemView];
if(![view isActive]) return NO;
}
return YES;
}
You will check for the class of the window, if it matches the NSStatusBarWindow we can then check somehow if the NSStatusItem is active. If it is, that means we have to return YES, because this way the NSPopover from NSStatusItem will have all keyboard events.
What I'm using for checking if the NSStatusItem was clicked (or is active) is that in my own custom view i have a bool value which changes when user clicks on the NSStatusItem, system automatically checks for "canBecomeKeyWindow" and when it does it will return NO and after user clicks on it (while it is returning the NO) it will change the bool value and return YES when system asks again (when NSPopover is being clicked for NSTextField editing).
Sidenotes:
CBStatusBarView is my custom view for NSStatusItem
CBAppDelegate is my App Delegate class
If anyone is still looking for an answer to this, I am working in Swift.
At the time where you wish the field to allow text entry, I have used myTextField.becomeFirstReponder()
To opt out; just use myTextField.resignFirstResponder()
Definitely a bug. That bug report is exactly what I was trying to do. Even down to creating the status item and overriding mousdown.
I can confirm that Balazs Toth's answer works. I just wonder if it might get in the way down the road.
If someone gets it and the solution above didn't do the trick for him.
The problem in my app was in the info tab in the targets my application was set to
Application is background only = true
and shulde of been
Application is agent = true
Spent an entire day on this thing.
Bug. http://openradar.appspot.com/9722231
http://iphonedevelopment.blogspot.com/2009/02/alert-view-with-prompt.html
I'm using that code to get my iPhone app to display an alertView with an included UITextField and matching CANCEL and OK buttons.
The user can enter text, hit CANCEL or OK... and I see the text the user entered... using my code inside the clickedButtonAtIndex method.
It all works except for 1 thing: Instead of OK, the user might hit DONE on the keyboard.
I'm using dismissWithClickedButtonIndex to simulate an OK click... but then clickedButtonAtIndex never gets called.
Shouldn't dismissWithClickedButtonIndex also call clickedButtonAtIndex?
I'm trying to get clickedButtonAtIndex to get called if CANCEL, or OK, or even DONE is hit.
Since this is an old question you've probably figured it out by now, but I was incredibly frustrated with this and couldn't find any help from Google, so for anyone who comes across this in the future: when you call dismissWithClickedbuttonIndex, the method that gets called is alertView:didDismissWithButtonIndex, not alertView:clickedButtonAtIndex. It behaves exactly the same way, and I can't figure out why they'd be two separate methods for what seems to be the same action, but there it is.
clickedButtonAtIndex is called when user actually clicks the button. Clicking the button may or may not dismiss the alert. the standard OK/Cancel buttons have the effect of dismissing the alert on click. If a click translates to dismiss or a dismissWithClickedbuttonIndex method is called, then did DismissWithButtonIndex is called.
I'm not sure whether I fully understand your question, but here is my try:
Firstly, you need to remove the if (buttonIndex != [alertView cancelButtonIndex]) from the example. This should work for the OK and CANCEL buttons.
To recognize the DONE key of the keyboard, use - (BOOL)textFieldShouldReturn:(UITextField *)textField of the UITextFieldDelegate. Here you could call [textField resignFirstResponder] to dismiss the keyboard.
Also, what to you do in clickedButtonAtIndex? Couldn't you create your own method and the call it when you need it?
I had the same problem with UIAlertView(Blocks) categoty
UIAlertView-Blocks
My solution:UIAlertView(Blocks) -> MYAlertView : UIAlertView
Sometimes method:- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex called. Sometimes it didn't call.
So... I tried to find solution in many sources. Then I'he created subclass of UIAlertView with absolutely same code. And my problem was solved. In fact it is little bit more difficult to use. But no more this intrusive bugs.