0

Ive been looking into IB_designable and it is a really awesome feature. However, one issue that I have with it is that for each view, I have to subclasses a UIView. And within that Subclass I have to specify the UI elements inside the initWithCoder: method and prepareForInterfaceBuilder:

However, I want to be able to specify the UI Elements OUTSIDE of the class.

I want to make a UIView subclass that has a public property of which I can set from the outside and see in Inter face builder.

Is this possible?

UPDATE:

I am aware of IBInspectible. This makes the property available in the Attributes inspector. This is not what I mean by external.

IB_DESIGNABLE
@interface DesignableLabel : UILabel
@end
@implementation DesignableLabel 
@end

@interface SomeClass : UIViewController {
    IBOutlet DesignableLabel *DL;
}
@end
@interface SomeClass
- (void)prepareForInterfaceBuilder {
    DL.text = @"Hello World"
}
@end

DesignableLable is a subclass of UILabel. UILabels have a text property. I want SomeClass to somehow set that property. Normally if I do that and run the app, it should show the string. However, to save myself the trouble of running the app, I want it to show up in Interface builder so I can see its value as I type.

DerrickHo328
  • 4,664
  • 7
  • 29
  • 50

2 Answers2

0

The public property you want to set externally (using your public API) has to be marked with the IBInspectable keyword. Ex:

 @property (readwrite) IBInspectable BOOL activityIndicatorOn;

You can find more info about this keyword on Apple's website.

yonel
  • 7,855
  • 2
  • 44
  • 51
  • That talks about adding a property to the Attributes inspector. That isn't really what I am asking... Please see my update. Hopefully it clarifies things... – DerrickHo328 Feb 11 '15 at 21:16
0

I will answer my own question so that other people may benefit. You can use User Defined Runtime Attributes to call a category method to set your IB_Designable object from the outside.

IB_DESIGNABLE
@interface DesignableLabel : UILabel
@end

@implementation DesignableLabel 
@end

@implementation DesignableLabel (Runtime_TheTextYouWant)
    - (void)setTheText:(BOOL)b {
        if (!b) return;
        self.text = "The text you want";
    }
@end

@implementation DesignableLabel (Runtime_SayHelloToMyLittleFriend)
    - (void)setMyLittleFriend:(BOOL)b {
        if (!b) return;
        self.text = "Say hello to my little friend";
    }
@end

I have created two categories for my DesignableLabel. Now if I place two UILabels into my ViewController in storyboard, and subclass both UILabel's to DesignableLabel, then for the first UILabel I can use the user defined runtime attribute by calling the key path

theText

With the type of boolean and set the check mark. Then that particular DesignableLabel Object will have the text specified in the setTheText: category method.

Similarly, for the second DesignableLabel object, you would use the user defined runtime attribute by calling the key path

myLittleFriend

Notice that the key path does not use the word "set" and it lower cases the first word. setMyLittleFriend: becomes myLittleFriend.

In conclusion, this saves you from having to make a subclass for EACH IB_DESIGNABLE object.

DerrickHo328
  • 4,664
  • 7
  • 29
  • 50