Cocoa Programming for Mac OS X - Aaron Hillegass [121]
@class ManagingViewController;
...
- (void)displayViewController:(ManagingViewController *)vc;
...
A pop-up button is basically a button with a menu. When the NIB file is loaded, you need to load the menu with an item for each controller. Add this code to MyDocument.m:
- (void)windowControllerDidLoadNib:(NSWindowController *)wc
{
[super windowControllerDidLoadNib:wc];
NSMenu *menu = [popUp menu];
NSUInteger i, itemCount;
itemCount = [viewControllers count];
for (i = 0; i < itemCount; i++) {
NSViewController *vc = [viewControllers objectAtIndex:i];
NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:[vc title]
action:@selector(changeViewController:)
keyEquivalent:@""];
[mi setTag:i];
[menu addItem:mi];
}
// Initially show the first controller
[self displayViewController:[viewControllers objectAtIndex:0]];
[popUp selectItemAtIndex:0];
}
Note that the tag of the menu item is set to the index of the controller in the viewControllers array that the menu item represents. We can use the tag in the action method that the menu items trigger:
- (IBAction)changeViewController:(id)sender
{
NSUInteger i = [sender tag];
ManagingViewController *vc = [viewControllers objectAtIndex:i];
[self displayViewController:vc];
}
Build and run the application. The pop-up button should enable you to jump back and forth between the two views.
Resizing the Window
What if the two views are radically different sizes? Wouldn’t it be nifty if the window would stretch and shrink to make the box fit the view perfectly? You are going to add that now.
Open the view XIB files and make the two views different sizes.
In MyDocument.xib, select the box and use the Size Inspector to make it resize with the window (Figure 31.5).
Figure 31.5. Size Inspector for Box
Select the window. In the Attributes Inspector, prevent the user from resizing the window (Figure 31.6).
Figure 31.6. Disable Resizing for Window
In MyDocument.m, add the following lines to the displayViewController: method:
- (void)displayViewController:(ManagingViewController *)vc
{
// End editing
NSWindow *w = [box window];
BOOL ended = [w makeFirstResponder:w];
if (!ended) {
NSBeep();
return;
}
NSView *v = [vc view];
// Compute the new window frame
NSSize currentSize = [[box contentView] frame].size;
NSSize newSize = [v frame].size;
float deltaWidth = newSize.width - currentSize.width;
float deltaHeight = newSize.height - currentSize.height;
NSRect windowFrame = [w frame];
windowFrame.size.height += deltaHeight;
windowFrame.origin.y -= deltaHeight;
windowFrame.size.width += deltaWidth;
// Clear the box for resizing
[box setContentView:nil];
[w setFrame:windowFrame
display:YES
animate:YES];
[box setContentView:v];
}
Build and run the app. When you change views, the window should resize to fit the new view.
Chapter 32. Core Data Relationships
It is time to delve a bit deeper into Core Data. In Chapter 11, you dealt with a single entity (Car). In most applications, you will have multiple entities and relationships between them. Core Data supports to-one relationships and to-many relationships (ordered or unordered).
In this exercise, there will be two entities: Employee and Department. An employee will work for one department. A department will have a set of employees; one employee (chosen from its set) will be a manager. Thus, there are three relationships (Figure 32.1).
Figure 32.1. The Data Model
Edit the Model
In this section, you are going to be extending the Departments project that you started in the previous chapter. Open MyDocument.xcdatamodel. Add two entities, Employee and Department.
An Employee will have the two attributes firstName and lastName, both strings, as well as a to-one relationship called department with Department. Add these properties (Figure 32.2).
Figure 32.2. Employee Entity
A Department will have an attribute deptName, a string; a to-many relationship called employees