• No results found

Other Interface Elements That Use KVO, KVC, and Core Data

In document Core Data 2nd Edition (Page 158-163)

OS X: Bindings, KVC, and KVO

8.4 Other Interface Elements That Use KVO, KVC, and Core Data

Although the previous sections show how to access the Core Data repository in our recipe application with KVO and KVC, let’s quickly review the other elements that, if we wanted or needed to, could be utilized to display the data in our application as well.

NSObjectController

NSObjectController shares a lot of similarities with the NSArrayController discussed earlier. However, unlike the NSArrayController, the NSObjectController is designed to represent one instance rather than an array of instances. A common usage of the NSObjectController is to represent the selected object of an NSArrayController, thereby making it clearer as to what data is being displayed in the interface elements that are bound to the NSObjectController, as opposed to an NSArrayController. Another common usage is to have an entire interface, such as a detail sheet or child window, be bound to the values within an NSObjectController and then have the File’s Owner reference and populate that NSObjectController. In this design, the File’s Owner (usually a subclass of NSWindowController) simply has to populate the NSObjectController with a call to -setContent:, and the entire UI is Other Interface Elements That Use KVO, KVC, and Core Data

147

Figure 30—Accessing an existing NSFormatter on an element

automatically populated. This again makes the maintenance of the code very easy and also improves readability.

NSOutlineView

If we wanted to change the look of our application, we could display a single NSOutlineView instead of the two table views we are currently using. With an NSOutlineView, we could display a list of recipes with a hierarchy of ingredients listed under them, as depicted inFigure 31, Outline view of recipes, on page 149.

NSOutlineView shares a lot in common with the NSTableView object. In fact, it is a subclass of NSTableView. The major difference is that the NSOutlineView displays data in both a column format as well as a hierarchal format. This changes how the data needs to be represented and accessed. Instead of a flat array of objects, the NSOutlineView expects the data to be in a tree structure. Fortunately, there is a controller designed just for that use: NSTreeController. Some care must be taken when working with Core Data and an NSOutlineView. In general, the NSOutlineView and the NSTreeController expect the data to be in a fairly organized state. NSTreeController expects each parent (or branch) to have children accessible via the same methods. This is a bit counterintuitive to having descriptive

Figure 31—Outline view of recipes

names for relationships between objects, and I normally implement accessors instead of making my relationships generic. For instance, if we had a recipe that has children named RecipeIngredients, I would add another accessor to that relationship called children, purely for the NSOutlineView to use. We discuss custom NSManagedObject classes in Chapter 1, Under the Hood of Core Data, on page 1.

Unlike its parent object, NSTableView, the NSOutlineView does not work as cleanly as we might expect. We can combine it with the NSTreeController, but we get a lot more functionality and control by implementing the data source protocol for the NSOutlineView instead of using the NSTreeController object.

NSTreeController

As discussed in NSOutlineView, on page 148, NSTreeController objects are primar-ily used by the NSOutlineView interface element. Although they can store any data that lends itself to a tree structure, they are best suited as a controller for NSOutlineView objects. Unfortunately, there is still quite a bit of work to be done with the NSTreeController, and the results we get from working with it can be unexpected and unclear. Therefore, I recommend skipping it at this time and implementing the data source protocol instead when working with tree data.

NSSearchField

The NSSearchField interface element is an extremely useful tool and can provide an extra bit of polish to an interface. Its primary purpose is to filter the objects in an NSArrayController. That may not seem like much, until we remember that, Other Interface Elements That Use KVO, KVC, and Core Data

149

thanks to KVO, any tables or interface elements associated with that NSArray-Controller will get updated automatically and instantly. This means if we put a search field into our application and link it to our NSArrayController of Recipe objects, our source list of recipes will automatically be filtered based on the user input into that NSSearchField. Even better, we don’t have to write any code!

All we need to do to implement it is configure the bindings for the NSSearchField. To accomplish this, we first add an NSSearchField to our application. In Figure 32, Adding an NSSearchField to our application, on page 150, we have decreased the vertical size of the recipe source list and inserted an NSSearchField above it.

Next, we configure its bindings.

Figure 32—Adding an NSSearchField to our application

As shown in Figure 33, NSSearchField bindings, on page 151, the NSSearchField interface element works with an NSPredicate. We write the predicate in the Predicate Format field, substituting $value for whatever the user inputs into the search field and using the controller key and value transformer to bind it to our data. In this example, we want to filter on the name of recipes;

therefore, we bind the NSSearchField to our recipe’s NSArrayController using the controller key of filterPredicate and a predicate of name contains[c] $value.

Once we add one predicate, another appears on the Bindings tab for the NSSearchField. This is so we can use a search field for more than one type of search. Each search will be shown in the drop-down on the NSSearchField, and the Display Name binding will be shown to the user. This allows us to create one NSSearchField that can search for recipe names, ingredients, descriptions, or anything else we may need.

Once the binding is complete, we are done adding a basic search field. Running the application shows that text entered into the search field impacts the list

Figure 33—NSSearchField bindings

of recipes, as shown in Figure 34, Search filter running against the recipe list, on page 151.

Figure 34—Search filter running against the recipe list

8.5 Wrapping Up

Now that we have an understanding of Cocoa Bindings, KVO, and KVC, what else can we add to our desktop application that is specific to the desktop? In Chapter 9, Spotlight, Quick Look, and Core Data, on page 153, we will look at additions to our application that will be used outside of our application.

Wrapping Up

151

In document Core Data 2nd Edition (Page 158-163)