Retired Document
Important: This document is targeted for Interface Builder version 3.0 and Xcode 3, which have been superseded by Xcode 4. Interface Builder plug-ins are not supported in Xcode 4, making this document irrelevant for contemporary product development.
The Plug-in Object
The plug-in object is Interface Builder’s initial entry point into your plug-in and is represented by the IBPlugin
class. You must provide a subclass of this object in your plug-in and configure it as the primary class of your plug-in bundle. Your plug-in object has one critical responsibility: provide the list of nib files identifying the objects your plug-in represents. Beyond that, you use the plug-in object to provide support for other features of your plug-in. For example, you use the plug-in object to implement a preferences window or customize objects as they are dragged out of the library window.
The following sections describe the tasks you can perform from your custom plug-in object. For additional information about the methods of the IBPlugin
class, see IBPlugin Class Reference.
Configuring the Library Nib Files
The main job of the plug-in object is to provide Interface Builder with information about the custom objects it supports. It does this by returning a set of nib file names from its libraryNibNames
method. These “library nib files” are so named because they contain the objects to be integrated into Interface Builder’s library window. Inside the nib file are one or more library object templates, which are special containers that hold the visual representation of the objects. Because not all objects have a direct visual representation, library template objects have accommodations for specifying both the real object and a visual placeholder for that object.
The best way to understand how the library object templates inside of a library nib file work is to look at an example. Figure 4-1 shows the default nib file that is created whenever you create a plug-in project using the Xcode template. This nib file contains two library object templates. The first of these objects contains a generic NSView
object. The second contains an NSButton
object that acts as a placeholder for an NSButtonCell
object. If you were to build and install the plug-in without modifying this nib file, Interface Builder would add two objects to the library window: a generic NSView
object and a button cell (represented visually by an NSButton
object). Dragging one of these objects out of the library window would instantiate the corresponding real object (either the NSView
or NSButtonCell
) in the user’s document. Because they are existing Cocoa objects, the user could then select and configure those objects before saving them with the document.
There is no magic to how library object templates work. They are simply views used to identify entries for the library window. The library object template itself is just a container into which you place a single child view. This child view provides the visual appearance of your library entry at runtime. In most cases, this child view is your custom view object. If your object does not descend from NSView
, or if it is a view but is too large or complex to recognize when scaled to fit the library window, you can instead place an image view in the library object template and use that view to display an iconic representation of your object. You can then use the representedObject
and draggedView
outlets of the library object template to associate the real objects to be added to the user’s nib file.
The representedObject
outlet of a library object template points to the object that should be added to a user’s nib file in place of the visual representation displayed in the library window. For custom objects that do not descend from NSView
, you would connect this outlet to an instance of your object that you added to the nib file. Similarly, if you use an image view to draw an iconic version of a view, you would connect this outlet to the actual view that should be added to the user’s nib file. If you do not configure this outlet, Interface Builder assumes the view embedded in your library object template is the object that should be added to the user’s nib file.
The draggedView
outlet points to the view that should be used during drag operations from the library window. Dragged views are commonly used to show the user the actual size of views as they are dragged out of the library window. If your plug-in contains a custom object that might be difficult to represent in the limited space available in the library window, you could use a custom icon for the library window and assign the actual view to the draggedView
outlet. In such a situation, your dragged view would also be the represented object of the entry, unless you specified a different object in the representedObject
outlet. For more information about setting up dragged views, see Using a Custom Dragged VIew.
Configuring a Library Object Template
Each new library nib file contains two library object templates already configured with some sample objects. You can reuse these existing templates or delete them and start from scratch. To reuse them, simply replace the contents of those templates with an appropriate view (usually either a generic view or an image view) and configure that view for your custom object.
To add new library object template, do the following in Interface Builder:
Open the Library Objects view in your nib file.
In the library window, select the Library > IB SDK group. This group contains a single entry, which is a library object template.
Drag the library object template from the library window to your Library Objects view. (If you want to resize the library object template, you can do so from the size pane of the inspector window. The width and height of a library object template are typically set to 80 pixels.)
Configure the Label, Path, Summary, and Description attributes in the inspector window. For information about what to put in these attributes, see Providing User Documentation for Your Custom Objects.
Continue configuring the library object template for your view or object as described in the sections that follow.
Once you have an empty library object template, you can begin configuring it. For each library object template, you should fill in the label, summary, and description fields in the inspector window. These fields provide help information to the user at runtime and are displayed in the library window. The label field provides the basic name of the item while the description field provides detailed information about its purpose. The summary field contains tool tip information and is displayed when the user hovers the mouse over the item.
Configuring a Custom View
To configure a library object template with a custom object that descends from NSView
, do the following:
Locate the generic Custom View object. (It is normally found in the Cocoa > Views & Cells > Layout Views group.)
Drag a custom view from the library window and drop it into an empty library object template. (Make sure you drop the custom view so as to make it a child of the template view.)
Select the custom view you just dropped and open the inspector window.
In the identity pane of the inspector, type the class name of your custom view in the Class field.
Save your nib file.
Configuring a Custom Non-View Object
To configure a library object template with a custom object that does not descend from NSView
, do the following:
Configure the object’s visual representation:
If you have not already done so, add the image you want to use for your object to your Xcode project. (Make sure the image is included in the Copy Bundle Resources build phase of your plug-in target.)
In Interface Builder, locate the Image Well object in the library window. (It is an instance of the
NSImageView
class and is normally found in the Cocoa > Views & Cells > Inputs & Values group.)Drag an image well from the library window and drop it into an empty library object template.
Select the image well and open the inspector window.
In the attributes pane of the inspector, select None from the Border popup menu.
In the Image field of the inspector, type the name of the image.
Configure the represented object:
In the library window, locate the generic Object. (It is normally found in the Cocoa > Objects & Controllers > Controllers group.)
Drag a generic Object from the library window to your document window, making it a top-level object of your nib file.
In the identity pane of the inspector, type the name of your custom object in the Class field.
Create the connection between the visual representation of your object and the actual object:
Control-click (or right-click) the library object template to display its connections panel.
Click and drag from the
representedObject
outlet to the custom object in your document window, as shown in Figure 4-2.
Using a Custom Dragged VIew
When the user drags your custom object out of the library window, Interface Builder uses the view inside the library-object template as the default drag image. If you want to use a custom drag image, you can do so by configuring the draggedView
outlet of the library object template.
A dragged view lets you provide the user with a more appropriately configured view. You might use a dragged view to provide a larger view than the one that appears in the library window. You might also use a dragged view to support a more complex view hierarchy. For example, for a table view item, you might display a table icon in the library window but assign a full-size table view embedded in a scroll view to the draggedView
outlet. The use of an icon in the library would let you provide a clear visual indicator of what your view represented while the dragged view provides the actual view.
The view you assign to the draggedView
outlet can be any size you like but must not be embedded inside a library object template. In most cases, you can simply place the view next to your library object template in your nib file, but you can also place it elsewhere in your nib file if doing so is more convenient. Once in your nib file, configure the view the way you want it to appear when dragged from the window.
To assign a dragged view, do the following:
Add a new view to your nib file to act as the dragged view. (Size it appropriately.)
Control-click (or right-click) the library template object containing your custom object to bring up its connection panel.
Click the circle next to the
draggedView
outlet and drag to your dragged view to create a connection.
Creating New Library Nib Files
If you are building a plug-in for a large library of controls, you can use multiple library nib files to organize your plug-in contents. Interface Builder lets you specify any number of library nib files in a single plug-in project, and each nib file can in turn contain multiple library object templates. For example, you could have five library nib files with one library object template each, or you could have one library nib file with five library object templates. Although there is no limit to the number of library nib files your project can include, there is a performance cost to loading many small nib files, so it is recommended that you use a reasonable number of nib files. Creating hundreds of library nib files would not only slow down the loading of your plug-in but would also be a lot of extra work.
You create library nib files the way you would create any nib file in Interface Builder. The new document panel includes an IB Kit tab that when selected shows you the types of nib files you can create for your plug-in. To create a new library nib file, select the Library object and click Choose. Interface Builder creates a new nib file like the one shown in Figure 4-1.
After you configure your library nib file and add it to your Xcode project, you need to update the libraryNibNames
method of your IBPlugin
subclass. Listing 4-1 shows a sample implementation of this method that returns the names of two custom nib files. You can return as many nib files from your own implementation of this method as you want. Each library nib file can contain one object or multiple objects.
Listing 4-1 The libraryNibNames method
- (NSArray *)libraryNibNames |
{ |
return [NSArray arrayWithObjects:@"myLibraryNibFile1", @"myLibraryNibFile2", nil]; |
} |
Registering Your Plug-in’s Object Frameworks
When you build your plug-in, you link it against the framework containing the code for your custom objects. Thus, when Interface Builder loads your plug-in at design time, it automatically loads your custom object frameworks as well. This is fine for manipulating your objects at design time but causes a problem during simulation. When the user simulates a window, Interface Builder launches an entirely separate process—one that does not load your plug-in code and therefore does not know about your object frameworks. In order to ensure that your objects work properly in the simulator environment, you should override the requiredFrameworks
method and return the list of frameworks containing your custom objects. Interface Builder passes this list to the simulator environment, which loads the corresponding frameworks as needed to run the simulation.
Listing 4-2 shows a sample implementation of the requiredFrameworks
method that searches for the desired framework using its bundle identifier string.
Listing 4-2 Returning the required frameworks of a plug-in
- (NSArray*)requiredFrameworks |
{ |
NSBundle* frameworkBundle = [NSBundle bundleWithIdentifier:@"com.mycompany.MyFramework"]; |
return [NSArray arrayWithObject:frameworkBundle]; |
} |
Handling Load and Unload Notifications
Most plug-ins should not require any special initialization, but if yours does, the IBPlugin
class provides notification methods to let you know when your plug-in is loaded into (or removed from) the Interface Builder environment:
didLoad
willUnload
Most plug-ins should have little need to use either of these methods. If you do use them, do not assume that calls to the didLoad
method will be balanced by calls to the willUnoad
method. Although Interface Builder calls the didLoad
method whenever your plug-in is loaded, it calls the willUnload
method only when the user explicitly removes your plug-in from the list of plug-ins in the preferences window. Therefore, you should not use your didLoad
method to acquire resources and the willLoad
method to release them. You may end up leaking those resources if you do. Instead, release any resources in the dealloc
or finalize
method of your plug-in object.
Implementing Plug-in Preferences
When the user selects your plug-in in the preferences window, Interface Builder displays additional information about the plug-in to the right of the plug-in list. By default, Interface Builder shows the list of library nib files and frameworks found in your plug-in but you can use this space to display custom preferences. Doing so is not required, however.
To display a custom preferences view, you must do the following:
Create a nib file with an
NSView
object as a top-level object.Set the File’s Owner of the nib file to your
IBPlugin
subclass. Your plug-in object should be configured to act as the controller for your preferences view.Add your custom content to the view object and connect any outlets and actions to Files Owner.
Override the
preferencesView
method in yourIBPlugin
subclass. In your implementation, load your nib file and return the view object you created.
Your plug-in object should contain all of the outlets, actions, or binding points needed to manage your preferences view. Other objects in your plug-in can access the information in your plug-in object by obtaining the shared plug-in object (using the sharedInstance
class method of IBPlugin
) and calling its methods.
Changing your Plug-in Bundle’s Principal Class
Your custom IBPlugin
subclass must be the principal class of your plug-in bundle. If you created your project using the Interface Builder 3.x Plugin project template, this information should be configured for you automatically. If you created your project without using the template or renamed your plug-in subclass, you must configure this information manually by doing the following:
Open an inspector window for your plug-in target.
Select the Properties tab.
In the Principal Class field, enter the name of your custom
IBPlugin
subclass.
Copyright © 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-03-08