We are in the process of implementing IBInspectable into a large app in hopes of allowing some settings to be set in Interface Builder to reduce the amount of code in our views. I don't have much experience with IBInspectable/IBDesignable and am looking for some answers and/or clarification on what I'm doing wrong.
I have declared a property in a UITableViewCell subclass as follows:
#property (nonatomic,strong) IBInspectable UIColor* backgroundColor;
When declaring the property like this, I get an option to set that color in Interface Builder > Attributes Inspector, which is to be expected. However when I set the color, the value for _backgroundColor is nil at runtime.
[_labelLoginBackground setBackgroundColor:_backgroundColor];
Could someone clarify what might be going here? Thanks!
UITableViewCell is a subclass of UIView, which already contains a property named "backgroundColor". Do 1 of the following:
Rename your own "backgroundColor" property to "loginBackgroundColor" and start debugging from there.
OR
Do not create a redundant property. Set the background color using the selection widget that is already present in Interface Builder before you ever add IBInspectable.
Related
After searching online I found that, if we declare a property inside a custom view as #IBInspectable, that property can be altered in the IB attribute inspector.
But my question is what is the use of #IBDesignable. Even if I don't declare a class as # IBDesignable, Im able to see the live rendering of the #IBInspectable properties
IBDesignable is user defined run time. Mean that if any IBDesignable view is rendered on the storyboard, you will find the view and change the value of the IBInspectable property, this will directly reflect on the storyboard without running the app.
IBInspectable is run time property, this works as key coding value. You can't find the change in storyboard, it will be applied in the run time.
The live rendering of a custom view should stop once you remove #IBDesignable. But sometimes this does not happen immediately.
If you remove #IBDesignable, then, close and reopen Xcode.
You should not see any live rendering the custom view directly in the canvas.
I am tired of setting property values to each UILabel in the IB. Is extending the UILabel the only possible way? or there exists some other way to do it?
You could create an IBOuletCollection for the labels and set the properties programmatically (in viewDidLoad for example) using:
[self.outletCollection setValue:whatever forKey:something];
You can also call makeObjectsPerformSelector on the collection in order to send messages to each label.
Assign all the properties to one UILabel
Copy paste the label as many times you want in storyboard or xib
New labels will also get the same properties, you just require to arrange their positions
Then you can go ahead with IBOutlets and manipulate with those
This applies to all the widgets in storyboard/xib.
Also as #dehlen metioned,
If you are using codebase for UI then, Custom Button Class
Inherit UIButton and create a subclass CustomButton
In its init method, assign all the properties which you require, like font, color etc
And assign frame value at use-time, through initWithFrame method.
Or
Add button in storyboard/xib, but in its class property change class name to CustomButton
Thanks #dehlen, You are right, I forgot to mention code side implementation.
After setting the property of a UILabel make copy of it by
Press and hold alt and drag and drop UILabel to another place it will create new copy of that UILabel with same properties.
In Xcode 6, can you have a UIButton property in your header file display in interface builder by setting the property as IBInspectable? The button is created entirely in code. Something like #property (nonatomic, retain) IBInspectable UIButton *directions;
I don't think uibutton are inspectable type. But why don't you just use a IBOutlet?
IBInspectable is just a way to design a set of none UI properties which can be then be accessible in IB to help you customize your class via the attribute inspector.
If you want to have a preview of your custom button, you should use IBDesignable, but in this case it doesn't apply to a property but a class.
IBDesignable allow to have a preview in IB of your view.
Check this article: http://www.weheartswift.com/make-awesome-ui-components-ios-8-using-swift-xcode-6/
I have a custom button, that is just a standard UIButton, but with a CAGradientLayer added in.
In my custom button, I have defined two properties:
#property (nonatomic, strong) UIColor* topColor UI_APPEARANCE_SELECTOR;
#property (nonatomic, strong) UIColor* bottomColor UI_APPEARANCE_SELECTOR;
If those two values get set, the my button draws itself with a nice linear gradient. Works great.
I also like to put as much into InterfaceBuilder as possible. So, on some of these buttons, in IB's "Identity Inpsector" I add in "User Defined Runtime Attributes" for these properties. Again, works great.
Next, I thought I'd try using UIAppearance proxies. Most of my custom gradient buttons all have the same colors. But there are a few that are different. So, I figured what I would do is use the appearance-proxy stuff to set the default colors for this class, and then for any buttons that are different, I could just set their values in IntefaceBuilder. This fails.
Apparently, what's happening is that it's reading the runtime attributes from my storyboard file first, but afterwards those values get overwritten by the appearance proxy. I wouldn't expect this to work this way, but it does.
Any tips on how to accomplish this? Or should I just give up on the runtime attributes thing?
OK, I've thought about this, and I guess this is really what the Appearance proxy is supposed to do. So, my solution is to have two classes "MySpecialButton" and "MyAppearanceButton".
MyAppearanceButton will be a sub-class of MySpecialButton.
The look of "MyAppearanceButton" will be controlled by the appearance proxy calls. If I want a button that isn't controlled that way, I'll make a "MySpecialButton" and set the properties in the User Defined Runtime Attributes. That should do it.
Making UI programmatically is very powerful.
But is there a way I would have missed to see for instance CG Graphics drawing in IB without to have to compile the code ?
I guess no, but I'd prefer to ask to refer that after :)
Nop, how would IB know what to draw without compiling the code?
The new answer to this question is: Yes.
With Xcode 6, you can make Interface Builder render your custom views. In addition, you can also make Interface Builder-inspectable properties on custom views that you can set from Interface Builder just like properties of built-in views.
All you need to do is add the line IB_DESIGNABLE just above the class declaration in the header. This will make Interface Builder render your custom view by invoking its drawRect: method.
If you also want the inspectable properties, just add IBInspectable to the property declarations such as: #property IBInspectable float myValue, and you will be able to set that property directly from Interface Builder.
With the combination of those two, I am currently designing a custom view and by changing the properties (color, stroke width etc) I can see the effects in realtime, which is probably just you were asking for.
It came a bit late, but finally, it's here.