How to implement my own selectAll: for UITextView without subclass it? - xcode

How do I implement my own selectAll: for UITextView without subclassing it? I don't want to subclass UITextView because if I do I need to change every place in my codes (.m/.xib) that need to use this subclass.
I had thought (wrongly!) that maybe I can connect UITextView action like selectAll: to my code (I do declare - (IBAction)select:(id)sender in my h file) ? I drag the action to File's Owner or to .h/.m file, nothing happens.
Now I know they are received action so I can't do that. Then how to ?

You cannot connect it because there is no such action. You are reading the Connections inspector incorrectly. The things in your screen shot are not actions. selectAll: is not an action. It is a received action. It is not emitted by the text view. It is sent to the text view, as a nil targeted action passing up the responder chain. To change or add to the text view behavior when it receives this action, you subclass UITextView. It's easy to do.

Related

How to get notified of clicks in a view-based NSTableView

I have a view-based NSTableView containing a list of words. When the user double-clicks on a word, I would like to take an action. The words are not editable or selectable. How do I do this?
I have tried setting the target and action of the table view in IB, but it only calls the action method when the user clicks in the header of the table, not in one of the words.
I have tried setting the target and action of the NSTextField that the table cell view keeps in IB. This results in this error message being repeated in the console:
2018-01-02 14:14:32.080347-0800 WordExplorer[7089:21457459] Could not connect action, target class NSObject does not respond to -relatedWordClick:
However the target class does respond to the selector. (I connected it in IB directly, so clearly, it does!) It is also not a simple NSObject, so I'm guessing that something else is going wrong there.
I have tried manually calling -setTarget: and -setAction: on the NSTextField contained in the table cell view in my delegate's -tableView:viewForTableColumn:row: method. This has no effect, and the debugger shows that despite calling those methods, they do not set the text field's action or target method. (Though, given this is Xcode we're talking about, it's likely that's just a debugger display issue.) I get no errors in the console like when I make the connection in IB, but it also does not call the appropriate method.
Do I need to make custom view class and use that for the table cell view? Or is there a simpler way to get clicks (and preferably double-clicks) on words in my list?
Simply create an IBAction on the object you have as the NSTableView's target, and then set the NSTableView's doubleAction property to the selector for that IBAction, and you can handle double-click events easily.

NSControl with multiple actions

I'm trying to create a complex custom NSControl that must be able to send more than one message.
For example, on mouse over in must send an action, and on mouse drag in must send another action.
I can't understand how to wire a target to a control and make the control sends whatever message to the target.
In my opinion i have to follow these steps:
Instantiate the NSControl i.e. myControl
set the Target action for myControl for every actions (I don't know how to do that!)
The myControl instance will send action with [NSApp sendAction: [self action] to: [self target] from: self]
Can you help me on step 2? and confirm my steps?
You need Delegation pattern. Standard Cocoa controls send at most one action, and use delegation for anything additional. IB does not support setting more than one action, so you can't solve step 2.
If delegate is an outlet, you can set it right from IB whenever the delegate is file's owner or also instantiated in this nib, like you would do that for e.g. NSWindow or NSTableView.

Clean way to resign first responder of NSSearchField when done?

In my application I have an NSSearchField that is bound to an arraycontroller which performs searches as the user types.
The problem is that the search field never resigns firstresponder-status once it receives it.
What would be the cleanest way of resigning firstresponder status when the user presses Enter or clicks outside of the search field? If possible I would prefer to do as much work as possible in Interface Builder.
[searchField.window makeFirstResponder:nil]
If you just want to get rid of the focus ring, you can disable it in the NIB.
If you want to resign first responder when the user clicks empty space in the window, you have to use a custom NSView as the window's content view and override mouseDown: to call the above method.

How can I receive actions listed in here? (Cocoa)

I'm trying to connection the actions to specific object in IB tree. When I drag the action from the circle on the right side of each action name, no object accepts the line except NSScroller instance.
NSWIndow, NSResponder or any other kind of objects doesn't accept the dragged action. What's required to accept the action listed here?
These are action messages that you can send to the selected object (i.e., that it can receive and respond to). You can drag from any of those circles to any object (most probably a control, most probably a button) that has a target and an action; doing so will set the control's target property to this object and the control's action property to the action you connected it to.
I decided to use a delegate method.
- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
Here's a usage: http://www.cocoabuilder.com/archive/cocoa/48070-adding-carriage-return-behavior-to-nstextview.html

How to make a view controller first responder for an NSView in Cocoa

I'm trying to implement a view controller for a custom NSOpenGLView based view (this is Cocoa, not Cocoa Touch).
The view is contained within a NIB loaded window but it does not have its own NIB. In fact the window contains multiple instances of the view.
I want to route mouse events to the controller instead of to the view. I would like for this to happen as soon as the user clicks within the corresponding view.
So how can this be done ?
I've tried having the view's becomeFirstResponder method call makeFirstResponder with the controller as argument. However that doesn't seem to work, the view still receives the mouse events instead of the controller if NSView::becomeFirstResponder returns YES. If it returns NO then neither of my classes receive the mouse events.
Of course I could implement the mouse event handling methods in the view and explicitly forward them to the controller but it seems like there should be a better way to handle this.
For general "first responder" status, I recommend Charles Parnot's MTViewController, an NSViewController subclass that uses KVO to make certain the controller is in the responder chain with no extra effort on your part.
However, in your case, you want mouse events too. There's really no way around this - your view will need to translate mouse events into controller interactions.

Resources