转载

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

前言:

在以前我们使用xib,SB,nib 设置一个view的圆角 边框需要通过一下界面非常的繁琐,所以一般情况下更倾向于使用代码来设置反而更加简单

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

在现在 IBInspectable 属性彻底的解决了这个问题:在 Xcode 6,你现在可以指定任何属性作为可检查项 来设置对应的属性

正题:

一、iOS8新特性IBDesignable(swift)/IBInspectable(oc),可以直接在XIB或者Storyboard中直接,设置UI类的属性。

例如:UIView.layer.borderWidth、borderColor、cornerRadius这些属性在XIB上是不能直接设置的,但是 IBDesignable/IBInspectable,利用runtime机制,就可以把这些属性映射到XIB上了,同时我们UI类的自定义属性也可以映射上 去。

二、IB_DESIGNABLE 的具体使用方法:

 IB_DESIGNABLE 的功能就是让XCode 动态渲染 出该类图形化界面;

使用 IB_DESIGNABLE 的方式,把该宏加在自定义类的前面;

当然还需要设置下xib的动态刷新要不然可能无法实时显示  具体设置见下图

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

三、下边附上自定义的demo代码 里边简单的实现了边框和 圆角的可视化修改

使用时候可以需将   view对应的class 改为customView

//CustomView.h文件  #import <UIKit/UIKit.h> IBInspectable @interface CustomView : UIView @property (nonatomic, assign)IBInspectable CGFloat cornerRadius; @property (nonatomic, assign)IBInspectable CGFloat BoderWidth; @property (nonatomic, assign)IBInspectable UIColor *BoderColor; @end  //CustomView.m文件  #import "CustomView.h" IB_DESIGNABLE @implementation CustomView  - (void)setCornerRadius:(CGFloat)cornerRadius{     _cornerRadius = cornerRadius;     self.layer.cornerRadius = _cornerRadius; } -(void)setBoderColor:(UIColor *)BoderColor {     _BoderColor = BoderColor;     self.layer.borderColor = _BoderColor.CGColor; } -(void)setBoderWidth:(CGFloat)BoderWidth {     _BoderWidth = BoderWidth;     self.layer.borderWidth = _BoderWidth;      }  @end

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

四、IBInspectable / IBDesignable封装

首先代码部分

// //  UIView+LCUtils.h //  iceTearsTest // //  Created by 冰泪 on 16/5/19. //  Copyright © 2016年 冰泪. All rights reserved. //  #import <UIKit/UIKit.h> IBInspectable @interface CustomView : UIView @property (nonatomic, assign)IBInspectable CGFloat cornerRadius; @property (nonatomic, assign)IBInspectable CGFloat BoderWidth; @property (nonatomic, assign)IBInspectable UIColor *BoderColor; @end   // //  UIView+LCUtils.m //  iceTearsTest // //  Created by 冰泪 on 16/5/19. //  Copyright © 2016年 冰泪. All rights reserved. //  #import "UIView+LCUtils.h" #import <objc/runtime.h>  @interface LCEdgeLayer : CALayer @property(nonatomic) UIEdgeInsets edges;  @property(nonatomic) UIColor *leftColor; @property(nonatomic) UIColor *topColor; @property(nonatomic) UIColor *rightColor; @property(nonatomic) UIColor *bottomColor;  @property(nonatomic) BOOL widthUnitInPixel; @end  @implementation LCEdgeLayer - (void)setLeftColor:(UIColor *)leftColor {     _leftColor = leftColor;     [self setNeedsDisplay]; } - (void)setRightColor:(UIColor *)rightColor {     _rightColor = rightColor;     [self setNeedsDisplay]; } - (void)setTopColor:(UIColor *)topColor {     _topColor = topColor;     [self setNeedsDisplay]; }  - (void)setBottomColor:(UIColor *)bottomColor {     _bottomColor = bottomColor;     [self setNeedsDisplay]; }  - (void)setEdges:(UIEdgeInsets)edges {     _edges = edges;     [self setNeedsDisplay]; } -(void)setWidthUnitInPixel:(BOOL)widthUnitInPixel{     _widthUnitInPixel = widthUnitInPixel;     [self setNeedsDisplay]; }  - (void)drawInContext:(CGContextRef)ctx {     const CGFloat ONE_PIXEL_WIDTH = 1.0 / self.contentsScale;     if (_edges.left > 0 && _leftColor) {         CGContextSetFillColorWithColor(ctx, _leftColor.CGColor);         CGRect rect = self.bounds;         if (_widthUnitInPixel)             rect.size.width = _edges.left * ONE_PIXEL_WIDTH;         else             rect.size.width = _edges.left;         CGContextFillRect(ctx, rect);     }          if (_edges.top > 0 && _topColor) {         CGContextSetFillColorWithColor(ctx, _topColor.CGColor);         CGRect rect = self.bounds;         if (_widthUnitInPixel)             rect.size.height = _edges.top * ONE_PIXEL_WIDTH;         else             rect.size.height = _edges.top;         CGContextFillRect(ctx, rect);     }          if (_edges.right > 0 && _rightColor) {         CGContextSetFillColorWithColor(ctx, _rightColor.CGColor);         CGRect rect = self.bounds;         if (_widthUnitInPixel){             rect.origin.x += (rect.size.width - _edges.right * ONE_PIXEL_WIDTH);             rect.size.width = _edges.right * ONE_PIXEL_WIDTH;         }         else{             rect.origin.x += (rect.size.width - _edges.right);             rect.size.width = _edges.right;         }         CGContextFillRect(ctx, rect);     }          if (_edges.bottom > 0 && _bottomColor) {         CGContextSetFillColorWithColor(ctx, _bottomColor.CGColor);         CGRect rect = self.bounds;         if (_widthUnitInPixel){             rect.origin.y += (rect.size.height - _edges.bottom * ONE_PIXEL_WIDTH);             rect.size.height = _edges.bottom * ONE_PIXEL_WIDTH;         }         else{             rect.origin.y += (rect.size.height - _edges.bottom);             rect.size.height = _edges.bottom;         }         CGContextFillRect(ctx, rect);     } } @end  @interface CALayer (Edge) -(LCEdgeLayer*) lc_findEdgeLayer; -(LCEdgeLayer*) lc_ensureEdgeLayer; @end   @implementation CALayer (Hook) #if !TARGET_INTERFACE_BUILDER + (void)load {     Method m1 = class_getInstanceMethod(self, @selector(lc_layoutSublayers));     Method m2 = class_getInstanceMethod(self, @selector(layoutSublayers));     method_exchangeImplementations(m1, m2); }  - (void)lc_layoutSublayers {     [self lc_layoutSublayers];          [self lc_findEdgeLayer].frame = self.bounds; } #endif  -(LCEdgeLayer*) lc_findEdgeLayer {     for (CALayer *layer in self.sublayers) {         if ([layer isKindOfClass:LCEdgeLayer.class]) {             return (LCEdgeLayer*)layer;         }     }     return nil; }  -(LCEdgeLayer*) lc_ensureEdgeLayer{          return [self lc_findEdgeLayer] ?: ({         LCEdgeLayer * edgeLayer = [LCEdgeLayer layer];         edgeLayer.contentsScale = [UIScreen mainScreen].scale;;         edgeLayer.frame = self.bounds;         edgeLayer.needsDisplayOnBoundsChange = YES;         [self insertSublayer:edgeLayer atIndex:0];                  edgeLayer;     }); }  @end   @implementation UIView (Edge)  #pragma -mark WIDTH - (CGFloat)edgeWidthLeft_lc{     return [self.layer lc_findEdgeLayer].edges.left; }  -(void)setEdgeWidthLeft_lc:(CGFloat)edgeWidthLeft_lc{     LCEdgeLayer * layer = [self.layer lc_ensureEdgeLayer];     UIEdgeInsets edges = layer.edges;     edges.left = edgeWidthLeft_lc;     layer.edges = edges; }  - (CGFloat)edgeWidthRight_lc{     return [self.layer lc_findEdgeLayer].edges.right; }  -(void)setEdgeWidthRight_lc:(CGFloat)edgeWidthRight_lc{     LCEdgeLayer * layer = [self.layer lc_ensureEdgeLayer];     UIEdgeInsets edges = layer.edges;     edges.right = edgeWidthRight_lc;     layer.edges = edges; }   - (CGFloat)edgeWidthTop_lc{     return [self.layer lc_findEdgeLayer].edges.top; }  -(void)setEdgeWidthTop_lc:(CGFloat)edgeWidthTop_lc{     LCEdgeLayer * layer = [self.layer lc_ensureEdgeLayer];     UIEdgeInsets edges = layer.edges;     edges.top = edgeWidthTop_lc;     layer.edges = edges; }  - (CGFloat)edgeWidthBottom_lc{     return [self.layer lc_findEdgeLayer].edges.bottom; }  -(void)setEdgeWidthBottom_lc:(CGFloat)edgeWidthBottom_lc{     LCEdgeLayer * layer = [self.layer lc_ensureEdgeLayer];     UIEdgeInsets edges = layer.edges;     edges.bottom = edgeWidthBottom_lc;     layer.edges = edges; }  - (BOOL)edgeWidthUnitInPixel_lc{     return [self.layer lc_findEdgeLayer].widthUnitInPixel; }  -(void)setEdgeWidthUnitInPixel_lc:(BOOL)edgeWidthUnitInPixel_lc{     [self.layer lc_ensureEdgeLayer].widthUnitInPixel = edgeWidthUnitInPixel_lc; }  - (CGFloat)edgeZPosition_lc{     return [self.layer lc_findEdgeLayer].zPosition; }  -(void)setEdgeZPosition_lc:(CGFloat)edgeZPosition_lc{     LCEdgeLayer * layer = [self.layer lc_ensureEdgeLayer];     layer.zPosition = edgeZPosition_lc; #if TARGET_INTERFACE_BUILDER     [layer removeFromSuperlayer];          for(CALayer * sub in self.layer.sublayers){         if(edgeZPosition_lc <= sub.zPosition){             [self.layer insertSublayer:layer below:sub];             break;         }     }          if(!layer.superlayer)         [self.layer addSublayer:layer];      #endif      }  #pragma -mark COLOR -(UIColor *)edgeColorLeft_lc{     return [self.layer lc_findEdgeLayer].leftColor; }  -(void)setEdgeColorLeft_lc:(UIColor *)edgeColorLeft_lc{     [self.layer lc_ensureEdgeLayer].leftColor = edgeColorLeft_lc; }  -(UIColor *)edgeColorRight_lc{     return [self.layer lc_findEdgeLayer].rightColor; }   -(void)setEdgeColorRight_lc:(UIColor *)edgeColorRight_lc{     [self.layer lc_ensureEdgeLayer].rightColor = edgeColorRight_lc; }  -(UIColor *)edgeColorTop_lc{     return [self.layer lc_findEdgeLayer].topColor; }  -(void)setEdgeColorTop_lc:(UIColor *)edgeColorTop_lc{     [self.layer lc_ensureEdgeLayer].topColor = edgeColorTop_lc; }  -(UIColor *)edgeColorBottom_lc{     return [self.layer lc_findEdgeLayer].bottomColor; }  -(void)setEdgeColorBottom_lc:(UIColor *)edgeColorBottom_lc{     [self.layer lc_ensureEdgeLayer].bottomColor = edgeColorBottom_lc; } @end   @implementation UIView(Border) -(UIColor *)borderColor_lc{     return [UIColor colorWithCGColor:self.layer.borderColor]; } -(void)setBorderColor_lc:(UIColor *)borderColor_lc{     self.layer.borderColor = borderColor_lc.CGColor; }  -(CGFloat)borderWidth_lc{     return [objc_getAssociatedObject(self, _cmd) floatValue]; }  -(void)setBorderWidth_lc:(CGFloat)borderWidth_lc{     objc_setAssociatedObject(self, @selector(borderWidth_lc), @(borderWidth_lc), OBJC_ASSOCIATION_RETAIN);          if(self.borderWidthUnitInPixel_l)         self.layer.borderWidth = borderWidth_lc / [UIScreen mainScreen].scale;     else         self.layer.borderWidth = borderWidth_lc; }  -(BOOL)borderWidthUnitInPixel_l{      return [objc_getAssociatedObject(self, _cmd) boolValue]; }  -(void)setBorderWidthUnitInPixel_l:(BOOL)borderWidthUnitInPixel_l{     objc_setAssociatedObject(self, @selector(borderWidthUnitInPixel_l), @(borderWidthUnitInPixel_l), OBJC_ASSOCIATION_RETAIN);          if(borderWidthUnitInPixel_l)         self.layer.borderWidth = self.borderWidth_lc / [UIScreen mainScreen].scale;     else         self.layer.borderWidth = self.borderWidth_lc;      }  -(CGFloat)borderCornerRadius_lc{     return self.layer.cornerRadius; }  -(void)setBorderCornerRadius_lc:(CGFloat)borderCornerRadius_lc{     self.layer.cornerRadius = borderCornerRadius_lc; }  -(UIColor *)borderLayerColor_lc{     return [UIColor colorWithCGColor: self.layer.backgroundColor]; }  -(void)setBorderLayerColor_lc:(UIColor *)borderLayerColor_lc{     self.layer.backgroundColor = borderLayerColor_lc.CGColor; }  -(BOOL)clipsToBounds_lc{     return self.clipsToBounds; }  -(void)setClipsToBounds_lc:(BOOL)clipToBounds_lc{     self.clipsToBounds = clipToBounds_lc; }  -(UIColor *)shadowColor_lc{     return [UIColor colorWithCGColor:self.layer.shadowColor]; }  -(void)setShadowColor_lc:(UIColor *)shadowColor_lc{     self.layer.shadowColor = shadowColor_lc.CGColor; }  -(CGFloat)shadowOpacity_lc{     return self.layer.shadowOpacity; }  -(void)setShadowOpacity_lc:(CGFloat)shadowOpacity_lc{     self.layer.shadowOpacity = shadowOpacity_lc; }  -(CGFloat)shadowRadius_lc{     return self.layer.shadowRadius; } -(void)setShadowRadius_lc:(CGFloat)shadowRadius_lc{     self.layer.shadowRadius = shadowRadius_lc; }  -(CGPoint)shadowOffset_lc{     CGSize size = self.layer.shadowOffset;     return CGPointMake(size.width, size.height); }  -(void)setShadowOffset_lc:(CGPoint)shadowOffset_lc{          self.layer.shadowOffset = #if TARGET_INTERFACE_BUILDER     CGSizeMake(shadowOffset_lc.x, -shadowOffset_lc.y); #else     CGSizeMake(shadowOffset_lc.x, shadowOffset_lc.y); #endif      }  @end  @interface LCLayoutConstraint : NSLayoutConstraint + (instancetype) constraintOfZeroAttribute:(NSLayoutAttribute) attr toView:(UIView*)view; @end @implementation LCLayoutConstraint + (instancetype) constraintOfZeroAttribute:(NSLayoutAttribute) attr toView:(UIView*)view{     return [self constraintWithItem:view attribute:attr relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0]; } @end   @implementation UIView(Visibility) - (LCLayoutConstraint*) findConstraintByAttribute:(NSLayoutAttribute)attr{     for(NSLayoutConstraint * con in self.constraints){         if([con isKindOfClass:LCLayoutConstraint.class] &&            con.firstAttribute == attr)             return (LCLayoutConstraint*)con;     }     return nil; }  - (LCLayoutConstraint*) ensureConstraintByAttribute:(NSLayoutAttribute)attr{     return [self findConstraintByAttribute:attr] ?:({         LCLayoutConstraint *con = [LCLayoutConstraint constraintOfZeroAttribute:attr toView:self];         [self addConstraint:con];         con;     }); }  - (BOOL)goneHorizontal_lc{     return [self findConstraintByAttribute:NSLayoutAttributeWidth]; }  -(void)setGoneHorizontal_lc:(BOOL)goneHorizontal_lc{     if(goneHorizontal_lc){         [self ensureConstraintByAttribute:NSLayoutAttributeWidth];     }else{         NSLayoutConstraint * cons = [self findConstraintByAttribute:NSLayoutAttributeWidth];         if(cons)             [self removeConstraint:cons];     } }  -(BOOL)goneVertical_lc{     return [self findConstraintByAttribute:NSLayoutAttributeHeight]; }  -(void)setGoneVertical_lc:(BOOL)goneVertical_lc{     if(goneVertical_lc){         [self ensureConstraintByAttribute:NSLayoutAttributeHeight];     }else{         NSLayoutConstraint * cons = [self findConstraintByAttribute:NSLayoutAttributeHeight];         if(cons)             [self removeConstraint:cons];     } }  @end   @implementation UIView(Xib) + (UIView*) lc_loadXibIntoView:(UIView *)view owner:(UIView *) owner{     NSString * xibName = NSStringFromClass(self);     NSBundle * bundle = [NSBundle bundleForClass:self];          UIView * contentView;          @try{         contentView = [bundle loadNibNamed:xibName owner:owner options:nil].firstObject;     }@catch(NSException * e){ #if TARGET_INTERFACE_BUILDER         @try{             contentView = [bundle loadNibNamed:[xibName stringByAppendingString:@"~iphone"] owner:owner options:nil].firstObject;         }@catch(NSException * e){             contentView = [bundle loadNibNamed:[xibName stringByAppendingString:@"~ipad"] owner:owner options:nil].firstObject;         } #else         @throw e; #endif              }     //required if we manually add sub view with constraints     contentView.translatesAutoresizingMaskIntoConstraints = NO;          [view addSubview:contentView];          [view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1 constant:0]];     [view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1 constant:0]];     [view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1 constant:0]];     [view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];          return contentView;      } @end  //set custom class to __cls to preview in IB @interface __UIView : UIView @end IB_DESIGNABLE @implementation __UIView @end   @interface __UILabel : UILabel @end IB_DESIGNABLE @implementation __UILabel @end  @interface __UIButton : UIButton @end IB_DESIGNABLE @implementation __UIButton @end  @interface __UIImageView : UIImageView @end IB_DESIGNABLE @implementation __UIImageView @end  @interface __UITextField : UITextField @end IB_DESIGNABLE @implementation __UITextField @end   

该代码可用于

UIView 、UILabel、UIButton、UIImageView、UITextField

可以设置独立的上、下、左、右、边框,四边的边框, 阴影,圆角

使用时候也非常简单

1、导入UIView+LCUtils.h/UIView+LCUtils.m 文件到项目中

2、只需要把对应的类换成__UIView(前边是两个下划线_) 、__UILabel、__UIButton、__UIImageView、__UITextField  其余地方不用做任何更改 和正常的写法一样即可 通过SB/xib/nib 的可视化面板来进行对边框 /圆角 /阴影的快速设置,能为我们编程节省很多时间

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

然后在设置里边将出现以下菜单选项 可以设置不同的属性

每日一搏 | IBInspectable / IBDesignable 可视化控件编程讲解/使用/封装

上边数据显示不是很全可以以代码作为参考 很好明白对应的是什么意思

//左边框
@property(nonatomic) IBInspectable CGFloat edgeWidthLeft_lc;
@property(nonatomic) IBInspectable UIColor * edgeColorLeft_lc;
//顶边框
@property(nonatomic) IBInspectable CGFloat edgeWidthTop_lc;
@property(nonatomic) IBInspectable UIColor * edgeColorTop_lc;
//右边框
@property(nonatomic) IBInspectable CGFloat edgeWidthRight_lc;
@property(nonatomic) IBInspectable UIColor * edgeColorRight_lc;
//下边框
@property(nonatomic) IBInspectable CGFloat edgeWidthBottom_lc;
@property(nonatomic) IBInspectable UIColor * edgeColorBottom_lc;

//边框开关
@property(nonatomic) IBInspectable BOOL edgeWidthUnitInPixel_lc;

@property(nonatomic) IBInspectable CGFloat edgeZPosition_lc;
@end

@interface UIView(Border)
//边框 颜色 宽度 以及是否开启边框
@property(nonatomic) IBInspectable UIColor * borderColor_lc;
@property(nonatomic) IBInspectable CGFloat borderWidth_lc;
@property(nonatomic) IBInspectable BOOL borderWidthUnitInPixel_l;
//圆角
@property(nonatomic) IBInspectable CGFloat borderCornerRadius_lc;
@property(nonatomic) IBInspectable UIColor * borderLayerColor_lc;
@property(nonatomic) IBInspectable BOOL clipsToBounds_lc;
//阴影
@property(nonatomic) IBInspectable UIColor * shadowColor_lc;//shadowColor阴影颜色
@property(nonatomic) IBInspectable CGFloat shadowOpacity_lc;//阴影透明度,默认0
@property(nonatomic) IBInspectable CGFloat shadowRadius_lc;//阴影半径,默认3
@property(nonatomic) IBInspectable CGPoint shadowOffset_lc;//shadowOffset阴影偏移,x向右偏移4,y向下偏移4,默认(0, -3),这个跟shadowRadius配合使
@end

最后附上demo http://git.oschina.net/zhfeiyue/CustomView1

转载请注明出处谢谢: http://my.oschina.net/iceTear/blog/679949

感觉写的不错的话可以关注我哦

原文  http://my.oschina.net/iceTear/blog/679949?fromerr=gMLXCwcL
正文到此结束
Loading...