how to get nstextfield from control:textView:doCommandBySelector - nstextfield

I have 6 textfield, and I want to know which field response to this method.
I can't transfer textView to textfield, what can I do ?
(BOOL)control:(NSControl *)control
textView:(NSTextView *)textView
doCommandBySelector:(SEL)commandSelector{
NSLog(#"commandSelector : %#",NSStringFromSelector(commandSelector));
//insertTab: -键入tab
//insertNewline: -键入回车
//deleteBackward
MSSingleField *field = (MSSingleField *)textView;
if ([NSStringFromSelector(commandSelector) isEqualToString:#"deleteBackward:"])
{
if (field.lastKeyView) {
[field.lastKeyView becomeFirstResponder];
}
}
return NO;
}

The control parameter is the text field.

Related

Adding Quicklook to an existing NSTableView

I've been searching high and low for an example of an easy implementation of Quicklook to an existing NSTableView and while I've found example projects they're way beyond my skill set to disassemble and duct-tape into my project.
I can get the Quicklook window to appear when a button is pressed using
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
But I haven't the slightest clue on how to set the data source so that the window is populated with the file.
Simply put, is there any stupid-simple tutorial on how to do this...?
Create a class that conforms to the QLPreviewItem protocol and implement:
- (NSURL *)previewItemURL {
// <Return File URL for file you want to preview>
}
Have your class that triggers the preview panel implement QLPreviewPanelDataSource, QLPreviewPanelDelegate and add the following to your implementation:
# pragma mark - QuartzPanel
- (IBAction)togglePreviewPanel:(id)previewPanel {
if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) {
[[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
} else {
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
}
}
- (BOOL)acceptsFirstResponder {
return YES;
}
- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel {
return YES;
}
- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel {
_previewPanel = panel; // create a property to hold a reference to your panel
panel.delegate = self;
panel.dataSource = self;
}
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
_previewPanel = nil;
}
#pragma mark - QLPreviewPanelDataSource
- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel {
return self.previewItems.count; // Items to preview of your custom subclass you created above
}
- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
return (id<QLPreviewItem>)self.previewItems[index];
}
#pragma mark - QLPreviewPanelDelegate
- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event {
// redirect all key down events to the table view
if ([event type] == NSKeyDown) {
NSString *key = [event charactersIgnoringModifiers];
if ([key isEqual:#" "]) {
[self togglePreviewPanel:self];
}
return YES;
}
return NO;
}

I can't get the UI Text View Keybord to disappear

Hi this is my code i am trying to get the UI text view keyboard to disappear. I have 2 text fields the second one is text view. I try and drag the action but it wont let me. Please help!!!!!
- (IBAction)dismiss1:(id)sender{
[sender resignFirstResponder];
}
- (IBAction)dismiss2:(id)sender2{
[field2 resignFirstResponder];
}
UITextView doesn't have event actions.
Import <UITableViewDelegate, UITableViewDataSource> in header file and use below code to disapear keyboard when click on return button.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"]) {
[self.textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return NO;
}
// For any other character return TRUE so that the text gets added to the view
return YES;
}

Get keyDown event for an NSTextField

In xcode last version, I am trying to get the keyDown event of an NSTextField.
However, despite following multiple tutorials on the internet (delegates, controllers...), I still can't receive it.
Any easy hint for me ?
Thanks !
I got sick of all the non answers to do it some other way people so I put my nose down and figured out a way to make this work. This isn't using keydown event directly but it is using the keydown in the block. And the behavior is exactly what I wanted.
Subclass the text field
.h
#interface LQRestrictedInputTextField : NSTextField
.m
In the become first responder setup a local event
static id eventMonitor = nil;
- (BOOL)becomeFirstResponder {
BOOL okToChange = [super becomeFirstResponder];
if (okToChange) {
[self setKeyboardFocusRingNeedsDisplayInRect: [self bounds]];
if (!eventMonitor) {
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event) {
NSString *characters = [event characters];
unichar character = [characters characterAtIndex:0];
NSString *characterString=[NSString stringWithFormat:#"%c",character];
NSArray *validNonAlphaNumericArray = #[#" ",#"(",#")",#"[",#"]",#":",#";",#"\'",#"\"",#".",#"<",#">",#",",#"{",#"}",#"|",#"=",#"+",#"-",#"_",#"?",#"#",
#(NSDownArrowFunctionKey),#(NSUpArrowFunctionKey),#(NSLeftArrowFunctionKey),#(NSRightArrowFunctionKey)];
if([[NSCharacterSet alphanumericCharacterSet] characterIsMember:character] || character == NSCarriageReturnCharacter || character == NSTabCharacter || character == NSDeleteCharacter || [validNonAlphaNumericArray containsObject:characterString ] ) { //[NSCharacterSet alphanumericCharacterSet]
} else {
NSBeep();
event=nil;
}
return event;
} ];
}
}
NSLog(#"become first responder");
return okToChange;
}
remove the event once the textfield editing ends
Also if you're using ARC I noticed you might need to assign the textview string to the stringValue. I nslog'd the stringValue and the value was retained. Without the nslog I had to assign the notification object string to the stringValue to keep it from getting released.
-(void) textDidEndEditing:(NSNotification *)notification {
[NSEvent removeMonitor:eventMonitor];
eventMonitor = nil;
NSTextView *textView=[notification object];
self.stringValue=textView.string;
}
You can subclass NStextField and use keyUp that works for NSTextField.
in .h
#interface MyTextField : NSTextField <NSTextFieldDelegate>
in .m
-(void)keyUp:(NSEvent *)theEvent {
NSLog(#"Pressed key in NStextField!");
}
Add UITextFieldDelegate to your .h like this
#interface ViewController : UIViewController <UITextFieldDelegate> {
Then you can use this to detect every key press in a text field
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Return YES to allow the character that was pressed to be inserted into the field but you can add whatever code you need in here.

IPad - how to only type 0~9 on textfield?

Hello
I know ipad keyboard doesn't like iphone can set "UIKeyboardTypeNumberPad"!!
But if I wanna it only can type and show number 0 to 9 on textfield.
How to compare what user key in on textfield are numbers or not ??
Thank in advance.
Mini
instead of comparing a figure after it is displayed, do it in the shouldChangeCharactersInRange
be sure to declare the delegate UITextFieldDelegate, and something i always forget, make sure the delegate of the textField itself is pointing at the class that has the code in it.
//---------------------------------------------------------------------------
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string length] == 0 && range.length > 0)
{
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
return NO;
}
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet];
if ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0)return YES;
return NO;
}
Take a look at this thread. It solved my similar problem.
How about How to dismiss keyboard for UITextView with return key??
The idea is you check every time the user hits a key, and if it is a number let it through. Otherwise ignore it.
Make your Controller supports the UITextViewDelegate protocol and implement the textView:shouldChangeTextInRange:replacementText: method.
(BOOL) textField: (UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string {
NSNumberFormatter * nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterNoStyle];
NSString * newString = [NSString stringWithFormat:#"%#%#",textField.text,string];
NSNumber * number = [nf numberFromString:newString];
if (number) {
return YES;
} else
return NO;
}

NSManagedObjectContext save causes NSTextField to lose focus

This is a really strange problem I'm seeing in my app. I have an NSTextField bound to an attribute of an NSManagedObject, but whenever the object is saved the textfield loses focus. I'm continuously updating the value of the binding, so this is far from ideal.
Has anyone seen anything like this before, and (hopefully) found a solution?
I encountered the issue recently and fixed it by changing the way the NSTextField was bound to the NSManagedObject attribute. Instead of binding the value of the text field to the selection.[attribute] key path of the NSArrayController, I bound the arrayController.selection.[attribute] keyPath of the view controller that had a proper outlet pointing to the controller.
For some reason, the NSTextField doesn't loose focus when the NSManagedObjectContext is saved if bound this way.
I want to share my solution. It will work for all fields without modification.
I have optimized it for this posting and removed some error checking, logging and thread safety.
- (BOOL)saveChanges:(NSError **)outError {
BOOL result = YES;
#try {
NSError *error = nil;
if ([self hasChanges]) {
// Get field editor
NSResponder *responder = [[NSApp keyWindow] firstResponder];
NSText *editor = [[NSApp keyWindow] fieldEditor: NO forObject: nil];
id editingObject = [editor delegate];
BOOL isEditing = (responder == editor);
NSRange range;
NSInteger editedRow, editedColumn;
// End editing to commit the last changes
if (isEditing) {
// Special case for tables
if ([editingObject isKindOfClass: [NSTableView class]]) {
editedRow = [editingObject editedRow];
editedColumn = [editingObject editedColumn];
}
range = [editor selectedRange];
[[NSApp keyWindow] endEditingFor: nil];
}
// The actual save operation
if (![self save: &error]) {
if (outError != nil)
*outError = error;
result = NO;
} else {
result = YES;
}
// Now restore the field editor, if any.
if (isEditing) {
[[NSApp keyWindow] makeFirstResponder: editingObject];
if ([editingObject isKindOfClass: [NSTableView class]])
[editingObject editColumn: editedColumn row: editedRow withEvent: nil select: NO];
[editor setSelectedRange: range];
}
}
} #catch (id exception) {
result = NO;
}
return result;
}
OK, so thanks to Martin for pointing out that I should read the docs a little more closely. This is expected behaviour, and here's what I did to get around it (use your judgement as to whether this is appropriate for you):
I save my context once every 3 seconds, checking at the start if the context has any changes before I bother executing the actual save: method on my NSManagedObjectContext. I added a simple incrementing/decrementing NSUInteger (_saveDisabler) to my Core Data controller class that is modified via the following methods:
- (void)enableSaves {
if (_saveDisabler > 0) {
_saveDisabler -= 1;
}
}
- (void)disableSaves {
_saveDisabler += 1;
}
Then all I do in my custom saveContext method is do a simple check at the top:
if (([moc hasChanges] == NO) || (_saveDisabler > 0)) {
return YES;
}
This prevents the save from occurring, and means that the focus is not stolen from any of my custom textfield subclasses. For completeness, I also subclassed NSTextField and enable/disable saves in my Core Data controller from the following methods:
- (void)textDidBeginEditing:(NSNotification *)notification;
- (void)textDidEndEditing:(NSNotification *)notification;
It might be a little messy, but it works for me. I'm keen to hear of cleaner/less convoluted methods if anyone has done this successfully in another way.

Resources