Cocoa : Detect changes to any form element - objective-c

I have a form built in interface builder.
Now I want to receive a notification when any element that is a child of a particular view is changed (be it text, or the select element, or a checkbox, etc).
Basically I want to know whether or not the form is "dirty" (changed).
How can I accomplish this?

One simple answer is to connect those UI elements which might change the value of the data model to an IBAction in the parent view controller. In that IBAction you can decide if you want to save the data, present a dialog, etc.

Related

What is the best practice of propagating variable value in Yii

I have a menu which pass parameters when a user click on one of the items menu.
When a user click an item menu, a view is lauched and call another view which call another view...
Can you tell me what is best practice on passing parameter from view to view.
Do I have to pass from view 1 to view2 and so on ..(as I did but I dont find it very clean) or it is another better way to do this.
I must say that I cannot put the value at the tpp of my controller because at that moment I do not know which menu wil be clicked.
Thanks for your reponse
I assume you are talking about views inside other views http://www.larryullman.com/2011/02/15/rendering-view-files-in-yii/ otherwise the question does not make a lot of sense.
The view has access to all the controller variables. So you can define a variable for the controller and you will be able to access it all the time in any of the nested views with $this->variable. You can actually put it at the top of the controller because that never changes while you are creating the views. That is 1 request, it should not change while you are processing the views.
If you are trying to make some ninja html, creating html with ajax based on what multiple menus the user clicks you can always save something in the session/cache and use that part but cleaner is to pass the argument through the entire process.

Changing visibility of NSPopUpButton's items based on keypress

I've got an application here that needs to read in a bunch of data from an external file and display it as a NSPopUpButton in a Cocoa user interface. The catch here is that the data that is being read in needs to have a flag that states if it is considered "hidden" or not.
If the data is hidden, it needs to be added to the NSPopUpButton as an NSMenuItem, but the hidden flag needs to be set to YES so it does not normally appear in the NSPopUpButton menu. If the user holds down a "magic key" on their keyboard (usually ALT, in this case) then those hidden objects need to be unhidden. If the user lets go of the ALT key, then they need to be automatically re-hidden, except for the one that may have been selected -- which would become hidden if another NSMenuItem were chosen.
I'm kind of having a heck of a time figuring this out, actually.
I was wondering if there is a straight forward way of doing this using NSArrayController and an NSPopUpButton, but thus far I have not been able to find anything resembling a solution -- not when it comes to managing the hidden property of the NSMenuItem objects.
Does anyone know how this can be achieved using Cocoa Bindings?
You can wire the popup to an array controller and alter the filter predicate. From an MVC design standpoint, you wouldn't use an attribute like "hidden", which is a view characteristic, but maybe "advanced". Normally, set a filter predicate on your array controller to "advanced = no". Then when the user holds your preferred modifier, remove the predicate. The popup will update automatically. The array controller should be bound to an array property on another object (in your data model). The popup should be bound to arrangedObjects on the array controller.

How to access methods/variables from swapped custom view

I've created a window that contains an NSSplitView in which case the right custom view has a view that I swap into at runtime. The custom view swapped in contains a NSTableView with data inside it. I have a search box in the main window of the application that I want to be able to constrain the rows of the table view with.
I have the code to do this and I know it works, but the code I have was tested with a search text box and table view that were on the same window scope. With the text search box now being in the main window and the table view being in a different custom view, I'm not sure how to get the text search box to call the relevant methods from the custom view's controller class, because I don't have direct access to these method anymore.
I'm sure this is a very beginner question, but any help would be appreciated. Thanks.
Have your main window controller pass the search query or filter predicate to a property of the content view controller.
You can give the main window controller a weak-referencing (assign) property that holds the current content view controller. Implement a custom setter that not only assigns to the backing instance variable, but also does the swap. That, any time it's time to do a swap, you simply say self.currentContentViewController = viewControllerToSwapIn, and when it's time to change the query/predicate, you pass it to self.currentContentViewController.searchQuery (having implemented the searchQuery property in the MainContentViewController class and made all your actual content-view controllers inherit from that class).

How should I do this? (iOS plist editing and updating all controllers)

I am making an app which basically presents data (from plist) to user in table form. I have a lot of controllers and the user basically navigates through these controller to get to an item after which a final detail display is shown.
At that last view, the user can add that to favorites.
The way that I am passing data to view controller is that I pass them specific data, so at the last view, if the user adds the item to favorites, I write that data to file. But how can I tell all my other controller that the data has updated?
This is more of a design problem and I don't know where to go..I have some idea but I want to know what is the standard way of doing this...Thanks.
If you're going to be listening for events within multiple objects, take a look at NSNotificationCenter. You can simply subscribe to listen for notifications then post one once the data is updated.
NSNotificationCenter Class Reference

Objective-C & Interface Builder for Dummies: How do I bind the keyboard?

So, I've been reading through other questions on here and Xcode's documentation, but I'm still a bit confused. Here's the scenario: I have a login screen for my app which has 3 text fields and 1 button. Each text field is bound to have a Return Key in IB: Next, Next, Go.
Now, how do I bind these return keys to actual actions where field 1 moves to the next, then field 2 moves to the next, and last field 3 triggers the button?
Some answers for similar questions suggest the use of textFieldShouldReturn method, but I'm still fuzzy on it. Somehow I can't see how it auto-magically knows what to do without having some kind of binding...
What you need to do is use an IBAction to select the next field when the return key is pressed. To do this, first add a method like this to your UIViewController. Make sure to add the method declaration to your header.
- (IBAction)selectSecondField:(id)sender
{
//_secondField is the IBOutlet to the second field
[_secondField becomeFirstResponder];
}
Build and then go to Interface Builder. Select the first text field and open the connections inspector (⌘2) and drag from the dot next to "Did End On Exit" to your controller with the action. A menu of actions will pop up, select selectSecondField.
You will need an action for each field. Alternatively, you could have one action and use sender to see which field was returned.
There's a handle (in the connections panel) on each text field called "nextfield" or something along those lines? (I can't remember off the top of my head) But if you drag that to the next box, that's how it knows (manually). I think generally it guesses using the X/Y location, but when you need to manually do it, just drag that handle.