Not so much a cheat sheet, but a general procedure to follow. Consider this class, a UILabel that draws an outline around it that you can customize and more importantly, view from Interface Builder:
#import IB_DESIGNABLE @interface HSOutlinedLabel : UILabel @property (nonatomic, assign) IBInspectable CGFloat outlineWidth; @property (nonatomic, assign) IBInspectable UIColor *outlineColor; @property (nonatomic, assign) IBInspectable CGFloat cornerRadius; @property (nonatomic, assign) IBInspectable CGPoint padding; // between the text and outline @end
and then the .m
#import "HSOutlinedLabel.h" @implementation HSOutlinedLabel - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self _commonInit]; } return self; } - (void)_commonInit { // gets called first (initWithCoder:), before any of the settings in IB are used. self.layer.masksToBounds = YES; _outlineWidth = 0; _outlineColor = nil; _cornerRadius = 5; _padding = CGPointZero; self.layer.cornerRadius = _cornerRadius; } - (void)prepareForInterfaceBuilder { // careful! this will overwrite any settings in Interface Builder. // it's meant for setting values that perhaps aren't IBInspectable [super prepareForInterfaceBuilder]; } - (void)awakeFromNib { if (_outlineWidth > 0) { self.layer.borderWidth = _outlineWidth; if (_outlineWidth > 0) { self.layer.borderColor = _outlineColor ? _outlineColor.CGColor : NULL; } else { self.layer.borderColor = NULL; } } } #pragma mark - Setters (Are used by Interface Builder) // NOTE: Interface Builder calls setValue:forKey: when you change // an inspectable value. If you are purely drawing your UIView subclass // with -drawRect: then these changes update. // However, if you see the setters below, I use the IBInspectables // to ultimately wrap CALayer properties. If you want your view to // draw correctly, you need to write accessors for any IBInspectable // that triggers changes to any object that won't necessarily be done // in drawRect: - (void)setOutlineWidth:(CGFloat)outlineWidth { if (_outlineWidth != outlineWidth) { _outlineWidth = outlineWidth; self.layer.borderWidth = outlineWidth; } } - (void)setOutlineColor:(UIColor *)outlineColor { if (_outlineColor != outlineColor) { _outlineColor = outlineColor; self.layer.borderColor = outlineColor.CGColor; } } - (void)setCornerRadius:(CGFloat)cornerRadius { if (_cornerRadius != cornerRadius) { _cornerRadius = cornerRadius; self.layer.cornerRadius = cornerRadius; } } - (void)setPadding:(CGPoint)padding { if (!CGPointEqualToPoint(_padding, padding)) { _padding = padding; [self invalidateIntrinsicContentSize]; } } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; size.width += 2 * _padding.x; size.height += 2 * _padding.y; return size; } @end
I just meant this to be a starting point for your own work. And actually a reminder for myself.