Multiple IBActions for a single UI event - objective-c

I'm a bit embarrassed to ask this one... if I want two very different things to happen when, say, a UIButton is used, can I hook this up in Interface Builder? I can't find a way to add multiple actions to the event.
The obvious answer is to have a single action connected, and perform both methods in the same block of code. But I quite liked the button action being connected to 'saveItem' instead of some generic 'buttonPressed' method.
I suppose I could also add the actions in code.

Unfortunately, there's not a way to do this with the builtin UI classes. You'll have to hook up to a single IBAction, then call through to the methods you want to call.

Related

How to see selected method's full name on Xcode completion popup

I'm trying to implement a delegate method in Xcode, and I see many methods looking very similar as their names/signatures are truncated:
For example, there's no way to distinguish which method is selected and which method is the one right below the selected one, and this is just one example. I have the same problem whenever there's a delegate involved with long method names and I'm trying to implement one of its methods. The popup is meant to be useful and in cases like this, it's extremely counter-intuitive.
Is there any way to display/distinguish the full method names?

What's the perferred event to handle the end of user interaction with a UIControl?

I have a view with multiple dynamically created UITextfields and UISegmented controls on it (but for purposes of this question, there could also be UIButtons, UISwitches, UISliders, or anything else that inherits from UIControl). I want to preform an action whenever the user finished interacting with any of the controls, regardless of what subclass of control it belongs to. From looking at other questions, I think I want to use addTarget:action:forControlEvents: to add observers to each of my controls after they are created, but I don't know which event I'm looking for. I've tried all the ones that are listed in the Apple Docs here that seemed relevant but none of them seem to be triggered everytime. I'm looking for something like .LostFocus in VBA, but I can't seem to find out what that is - I know there is a becomeFirstResponder method to make a control active, but I can't find anything like a "lostFirstResponder" event.
I suppose I could use isKindOfClass to tell what kind of control it is, and set up my event accordingly, but that seems a little sloppy and I feel like there should be a more direct way to do it. I could also probably set up a UITapGestureRecognizer and build up something that way, but that still feels like a workaround and not really the way it's supposed to be done.
If you're willing to subclass, you can override -resignFirstResponder to detect lost "focus", and act accordingly. This is probably only useful for things like textfields which can hold first responder status, and would not work for UISwitch for instance.
Since all UIControl objects are just UIViews, you can also override touchesEnded to detect the end of interaction with these elements.. although the more accepted way is to add your dismissal handler method as an action for all the UIControlEvents that indicate end of interaction, or just UIControlEventValueChanged.
More info on UIResponder here from Apple's Documentation:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/resignFirstResponder
Many UIKit classes have delegate methods that indicate when interactions have ended, for instance UITextField has a textFieldDidEndEditing method. UITextView has similar methods.

What is the different between `add target` and `implements a delegate` in objective C?

For example, I make a MyUIElement, I can accept the user click it. When the user click it, the user can define a method for me when I click it. For example, they can increase the count by 1, when I click it.
So, if I am thinking on how to implement this logic...I can make a MyUIElementDelegate, and call back the MyUIElementDelegate' s onMyUIElementIsClicked: function, or I can allow user to addTarget: action: forEvents:. These two ways also works. But what is the different between them? Thanks.
Well, if the method to be called is on the same class, addTarget would be easier but if the method is defined in another class, implementing delegate would be a better idea to invoke the method. With a little bit of extra coding, delegate protocol will give you more flexibility, by the fact that it has two types of methods: #required and #optional.

Cocoa: Actions Processing

the book which I study, to transition from C++ to Objective-C, places all the Action Methods into Application Delegate class.
The sample code within the book works. However, I am thinking, what if I have 100, or in extreme cases 500, controls in my application. Will all the controlls' actions be processed in the same Application Delegate class? This look to me as very messy.
Could you, therefore, help me to answer my question, please:
If I have many controls (buttons, processing bars, fields ... ) in my application, is Application Delegate the only and correct place for processing all the action methods?
No.
Books use the Application delegate because it is a convenient place to put example code.
As you write your own programs, you'll have your own hierarchy of controllers to receive action messages.

Logging all cocoa events?

I'm doing usability testing and would like to log all user input events: mouse movements, clicks, drags, and keyboard input. I'm not having much luck figuring out how, or finding any code to do so. Any hints? I took a look at the CoreGraphics EventTap mechanisms, but I'm worried that it will be too low-level; I'd like to actually know what particular UI elements the user clicks on.
Edit to clarify:
I'm doing usability testing, so I want to keep track of what parts of the interface the user uses and doesn't use. So, I want to keep track of "Button 'foo' was clicked 7 times at these particular timestamps, the user scrolled through this list and selected such-and-such item" and so forth.
If you're just looking to track them for your application, you could override -[NSApplication sendEvent:]. It's responsible for dispatching all the events your application receives to the appropriate responders.
I think you'll need to do a lot of swizzling.
Try swizzling tryToPerform:with: first; if that doesn't work, you'll need to swizzle such methods as mouseDown:, mouseUp:, the drag event methods, keyDown:, keyUp:, and the undocumented gesture methods.
One complication in the latter solution is that you'll need to swizzle those methods on not just NSResponder, but on several of its subclasses, because many view classes provide their own implementations, which may or may not call up to their ancestors' implementations.
Instruments has a way to record user interface events. It seems like you might be able to use the dtrace calls that underlie this to accomplish what you're going for.
This is completely different than what you're thinking about right now, but consider something like Silverback if you haven't yet.