Cocoa Programming for Mac OS X - Aaron Hillegass [74]
If a standard Cocoa object has a delegate and posts notifications, the delegate is automatically registered as an observer for the methods it implements. If you are implementing such a delegate, how would you know what to call the method?
The naming convention is simple: Start with the name of the notification. Remove the NS from the beginning and make the first letter lowercase. Remove the Notification from the end. Add a colon. For example, to be notified that the window has posted an NSWindowDidResizeNotification, the delegate would implement the following method:
- (void)windowDidResize:(NSNotification *)aNotification
This method will be called automatically after the window resizes. You can also find this method listed in the documentation and header files for the class NSWindow.
Challenge
Make your application beep when it gives up its active status. NSApplication posts an NSApplicationDidResignActiveNotification notification. Your AppController is a delegate of NSApplication. NSBeep() will cause a system beep.
Chapter 15. Using Alert Panels
Occasionally, you will want to warn the user about something by means of an Alert panel. Alert panels are easy to create. While most things in Cocoa are object oriented, showing a modal Alert panel is typically done with a C function: NSRunAlertPanel(). Here is the declaration:
NSInteger NSRunAlertPanel(NSString *title,
NSString *msg,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton, ...);
The following code would result in the Alert panel shown in Figure 15.1:
NSInteger choice = NSRunAlertPanel(@"Title", @"Message",
@"Default", @"Alternate", @"Other");
Figure 15.1. Example Alert Panel
Note that the icon on the panel will be the icon for the responsible application. The second and third buttons are optional. To prevent a button from appearing, replace its label with nil.
The NSRunAlertPanel() function returns an int that indicates which button the user clicked. There are global variables for these constants: NSAlert DefaultReturn, NSAlertAlternateReturn, and NSAlertOtherReturn.
Note that NSRunAlertPanel() takes a variable number of arguments. The second string may include printf-like tokens. Values supplied after the otherButton label will be substituted in. Thus, the following code would result in the Alert panel shown in Figure 15.2:
NSInteger choice = NSRunAlertPanel(@"Title", @"Message can have %@",
@"Default", @"Alternate", nil,
@"Format Specifiers");
Figure 15.2. Another Example Alert Panel
Alert panels run modally; that is, other windows in the application don’t receive events until the Alert panel has been dismissed.
Alerts can also be run as a sheet.
Make the User Confirm the Deletion
If the user clicks the Remove button, an Alert panel should appear as a sheet before the records are deleted (Figure 15.3).
Figure 15.3. Completed Application
To enable this behavior, open RMDocument.xib, select the table view, and open the Attributes Inspector. Allow the user to make multiple selections (Figure 15.4).
Figure 15.4. Inspect Table View
You now want the Remove button to send to RMDocument a message which will ask the user to confirm the deletion. If the user confirms this choice, RMDocument will send the removeEmployee: message to the array controller to remove the selected Person objects.
In Xcode, open the RMDocument.h file and add the method that will be triggered by the Remove button:
- (IBAction)removeEmployee:(id)sender;
In RMDocument.m, implement the removeEmployee: method that will start the Alert panel as a sheet:
- (IBAction)removeEmployee:(id)sender
{
NSArray *selectedPeople = [employeeController selectedObjects];
NSAlert *alert = [NSAlert alertWithMessageText:
@"Do you really want to remove these people?"
defaultButton:@"Remove"
alternateButton:@"Cancel"
otherButton:nil
informativeTextWithFormat:@"%d people will be removed.",
[selectedPeople count]];
NSLog(@"Starting alert sheet");
[alert