I've got a viewController xib file in which I've designed a button with the following characteristics (taken from the xib file)
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HKv-Bv-6j3">
<rect key="frame" x="126" y="9" width="250" height="32"/>
<buttonCell key="cell" type="push" title="Disable" bezelStyle="rounded" alignment="center"
borderStyle="border" imageScaling="proportionallyDown" inset="2" id="YYS-ZL-U1e">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
now I wish to add arbitrary numbers of similar designed buttons programmatically. How can I convert the XML above into objective-c code.
The XML tags all relate to properties or methods on NSButton
. Some are custom settings, like frame
. Others are default values (like using the system font), in which case you wouldn't have to explicitly set them. Note that there are a few different objects as well - NSButtonCell
is part of this mix (the buttonCell
XML object). You don't need to instantiate that separately, but it's where you'll find some of the properties. You'd do something like this:
frame = NSMakeRect(126, 9, 250, 32); // x, y, width height
myButton = [[NSButton alloc] initWithFrame:frame];
myButton.translatesAutoresizingMaskIntoConstraints = NO;
myButton.title = @"Disable";
myButton.bezelStyle = NSBezelStyleRounded;
myButton.alignment = NSTextAlignmentCenter;
myButton.imageScaling = NSImageScaleProportionallyDown; // default value
...
That's not a complete reproduction, but you should get the idea. Note that some of these properties are defined in NSButton
, but others (like alignment
) are defined in a superclass, e.g. NSControl
.
That is one way to do it. A more "Cocoa" solution is to create a XIB file with a single button and configure it to your liking. Then when you want a copy of it, load the XIB and grab it:
NSButton *myButton;
NSArray *topLevelObjects;
[[NSBundle mainBundle] loadNibNamed:@"MyCustomButton"
owner:self
topLevelObjects:&topLevelObjects];
for (id a in topLevelObjects) {
if ([a isKindOfClass:NSView.class]) {
myButton = a;
break;
}
}
If you place just the single button in the XIB, you won't need a dedicated controller. The code above loads the XIB then grabs the first NSView
it finds, which is your button. I like this method much more than the approach above since a) you don't have to decode the XML into a series of code statements, b) you can change the button's properties in Interface Builder anytime you want, and c) once you've loaded the button, you can make copies of it then.