IB_DESIGNABLE, having views show in preview?

2019-04-29 22:54发布

I have my views showing in interface builder with my IB_DESIGNABLE properties set, however when I use the preview feature to see how my views look on various devices, I just get the super view name, e.g. UIView.

Don't IB_DESIGNABLE views show in preview?

EDIT As requested code + screen shot:

H
=
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface TitleBannerView : UILabel
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;
@property (nonatomic) IBInspectable CGFloat shadowHeight;
@end

M
=
@implementation TitleBannerView
@synthesize borderWidth;
@synthesize cornerRadius;
@synthesize shadowHeight;

- (void)drawRect:(CGRect)rect {

    if (self.borderWidth == 0) self.borderWidth = 8.5;
    if (self.cornerRadius == 0) self.cornerRadius = 33;
    if (self.shadowHeight == 0) self.shadowHeight = 15.1;

    CGContextRef context = UIGraphicsGetCurrentContext();

    //// Color Declarations
    UIColor* bG = [UIColor colorWithRed: 0.18 green: 0.8 blue: 0.443 
       alpha: 1];
    UIColor* borderColor = [UIColor colorWithRed: 0.557 green: 0.267 blue: 0.678 
       alpha: 1];
    UIColor* shadowColor2 = [UIColor colorWithRed: 0.976 green: 0.859 blue: 0.718 
       alpha: 1];

    //// Shadow Declarations
    UIColor* shadow = shadowColor2;
    CGSize shadowOffset = CGSizeMake(-4.1, self.shadowHeight);
    CGFloat shadowBlurRadius = 1.5;

//

    //// Frames
    CGRect frame = self.bounds;

    //// Subframes
    CGRect group = CGRectMake(CGRectGetMinX(frame) + 15, 
        CGRectGetMinY(frame) + 15, CGRectGetWidth(frame) - 28, 
        CGRectGetHeight(frame) - 40);


    //// Abstracted Attributes
    CGFloat roundedRectangleStrokeWidth = self.borderWidth ;
    CGFloat roundedRectangleCornerRadius = self.cornerRadius;

    //// Group
    {
        //// Rounded Rectangle Drawing
        UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: 
           CGRectMake(CGRectGetMinX(group) + floor(CGRectGetWidth(group) * 0.00060) + 0.5, 
           CGRectGetMinY(group) + floor(CGRectGetHeight(group) * 0.00568) + 0.5, 
          floor(CGRectGetWidth(group) * 0.99940) - floor(CGRectGetWidth(group) * 0.00060), 
         floor(CGRectGetHeight(group) * 0.99432) - floor(CGRectGetHeight(group) * 0.00568)) 
         cornerRadius: roundedRectangleCornerRadius];
        CGContextSaveGState(context);
        CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, 
            shadow.CGColor);
        [bG setFill];
        [roundedRectanglePath fill];
        CGContextRestoreGState(context);

        [borderColor setStroke];
        roundedRectanglePath.lineWidth = roundedRectangleStrokeWidth;
        [roundedRectanglePath stroke];

    }
}
@end

The TitleBannerView is the view in green with purple border. enter image description here

3条回答
叛逆
2楼-- · 2019-04-29 23:29

IBDesignable works only in Interface Builder, but not in preview :-( I hope Apple fix it in new Xcode...

查看更多
We Are One
3楼-- · 2019-04-29 23:38

Do you have some mock data to display in interface builder?

When you use @ IBDesignable Your initializers, layout, and drawing methods will be used to render your custom view right on the canvas

Since the custom view won’t have the full context of your app when rendered in Interface Builder, you may need to generate mock data for display, such as a default user profile image or generic weather data. There are two ways to add code for this special context

  • prepareForInterfaceBuilder(): This method compiles with the rest of your code but is only executed when your view is being prepared for display in Interface Builder.
  • TARGET_INTERFACE_BUILDER: The #if TARGET_INTERFACE_BUILDER preprocessor macro will work in either Objective-C or Swift to conditionally compile the right code for the situation

You might want to take a look on this tutorial and example

查看更多
趁早两清
4楼-- · 2019-04-29 23:51

First, IBDesignable can be visible in preview.

Do you declare your IBDesignable class in a framework? IBInspectable ONLY supports preview when it's declared in a framework.

Also, keep in mind (not in your case):

  1. Your draw code should be fast enough, you only have 100ms draw time for an item.

  2. prepareForInterfaceBuilder() method is often needed.

查看更多
登录 后发表回答