文档章节

IBInspectable / IBDesignable可视化控件编程讲解/使用/封装

冰泪_
 冰泪_
发布于 2016/05/23 16:03
字数 1889
阅读 1122
收藏 12
点赞 2
评论 0

前言:

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

014.png

在现在 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的动态刷新要不然可能无法实时显示  具体设置见下图

 

三、下边附上自定义的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封装(导入项目之后可以对UIView 、UILabel、UIButton、UIImageView、UITextField使用)

 首先代码部分

//
//  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 的可视化面板来进行对边框 /圆角 /阴影的快速设置,能为我们编程节省很多时间

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

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

//左边框
@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

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

 

 

© 著作权归作者所有

共有 人打赏支持
冰泪_
粉丝 13
博文 68
码字总数 50702
作品 0
青浦
程序员
在Xcode6使用IBDesignable自定义控件

你有没有尝试过在旧版xcode里创建过自定义控件?不是很容易。主要是因为你在Interface Builder(以下简称IB)里看不到实时的效果,每次你要查看修改的效果,只能重新运行,这样很麻烦,你可能...

swingcoder ⋅ 2016/07/14 ⋅ 0

Swift学习 之 贝塞尔曲线 绘制表情

1、创建一个基于UIView名为FaceView的类 我们不直接在HappinessViewController(根视图控制器) 中实现,而是将FaceView完全独立出来,这正是遵循了MVC的设计原则。我们主要通过贝塞尔曲线来实...

魔笛GNR ⋅ 2016/07/17 ⋅ 0

iOS XIB约束适配 || 字体 根据屏幕宽变化

简单实现XIB上的约束值,按照指定需求自动变化(根据屏幕宽度变化)。 基准图(750 * 1334)上控件距离左边为20 达到效果:5s(640 1136)上运行距离为 20(320/375.0) = 17.07; 6s(750 133...

ShouldChang ⋅ 05/22 ⋅ 0

如何设计一个 iOS 控件?(iOS 控件完全解析)

[置顶] 如何设计一个 iOS 控件?(iOS 控件完全解析) 目录(?)[+] 代码的等级:可编译、可运行、可测试、可读、可维护、可复用 前言 一个控件从外在特征来说,主要是封装这几点: 对外在特征的封...

法斗斗 ⋅ 2016/01/04 ⋅ 0

如何设计一个 iOS 控件?(iOS 控件完全解析)

如何设计一个 iOS 控件?(iOS 控件完全解析) 一个控件从外在特征来说,主要是封装这几点: 对外在特征的封装,能让我们在多种环境下达到 PM 对产品的要求,并且提到代码复用率,使维护工作保持...

法斗斗 ⋅ 2016/03/16 ⋅ 0

Material 设计组件--MaterialKit

MaterialKit 是 Material 设计组件,使用 Swfit 编写。 高度定制 完整的示例 支持 @IBDesignable 支持 @IBInspectable MKButton : floating action button, raised button, flat button, ri......

叶秀兰 ⋅ 2014/11/17 ⋅ 0

[基础]iOS 可视化编程(全系列)

所有文章目录:http://my.oschina.net/ChenTF/blog/677112 本篇文章地址: http://my.oschina.net/ChenTF/blog/683042 会持续的更新所有历史文章, 所以收藏的话请收藏上面的地址。 1. 背景 本...

advancer_chen ⋅ 2016/05/27 ⋅ 3

iOS 活动指示器--KOActivityIndicator

KOActivityIndicator 是一款风格简易,用Swift写成的 IBDesignable 和 IBInspectable 活动指示器。

孔小菜 ⋅ 2015/03/13 ⋅ 0

Storyboard的爱与恨

尽管现在已经是Apple将Storyboard整合进Xcode中的第四个年头,大家对于Storyboard的评价仍然褒贬不一。有早期就选择转向Storyboard用于UI开发的国内业界领头人物,也有创建项目就立马删除Sto...

上官尘 ⋅ 2016/02/25 ⋅ 0

CRNetworkButton – iOS的发送按钮

欢迎来到CRNetworkButton – 高级按钮单击互动 GitHub 链接 - https://github.com/Cleveroad/CRNetworkButton 从Cleveroad认识一个新的iOS图书馆。 为了防止您对移动应用中的普通按钮点击感到...

David46 ⋅ 2016/11/10 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何优雅的编程——C语言界面的一点小建议

我们鼓励在编程时应有清晰的哲学思维,而不是给予硬性规则。我并不希望你们能认可所有的东西,因为它们只是观点,观点会随着时间的变化而变化。可是,如果不是直到现在把它们写在纸上,长久以...

柳猫 ⋅ 23分钟前 ⋅ 0

从零手写 IOC容器

概述 IOC (Inversion of Control) 控制反转。熟悉Spring的应该都知道。那么具体是怎么实现的呢?下面我们通过一个例子说明。 1. Component注解定义 package cn.com.qunar.annotation;impo...

轨迹_ ⋅ 23分钟前 ⋅ 0

系统健康检查利器-Spring Boot-Actuator

前言 实例由于出现故障、部署或自动缩放的情况,会进行持续启动、重新启动或停止操作。它可能导致它们暂时或永久不可用。为避免问题,您的负载均衡器应该从路由中跳过不健康的实例,因为它们...

harries ⋅ 25分钟前 ⋅ 0

手把手教你搭建vue-cli脚手架-详细步骤图文解析[vue入门]

写在前面: 使用 vue-cli 可以快速创建 vue 项目,vue-cli很好用,但是在最初搭建环境安装vue-cli及相关内容的时候,对一些人来说是很头疼的一件事情,本人在搭建vue-cli的项目环境的时候也是...

韦姣敏 ⋅ 35分钟前 ⋅ 0

12c rman中输入sql命令

12c之前版本,要在rman中执行sql语句,必须使用sql "alter system switch logfile"; 而在12c版本中,可以支持大量的sql语句了: 比如: C:\Users\zhengquan>rman target / 恢复管理器: Release 1...

tututu_jiang ⋅ 49分钟前 ⋅ 0

Nginx的https配置记录以及http强制跳转到https的方法梳理

Nginx的https配置记录以及http强制跳转到https的方法梳理 一、Nginx安装(略) 安装的时候需要注意加上 --with-httpsslmodule,因为httpsslmodule不属于Nginx的基本模块。 Nginx安装方法: ...

Yomut ⋅ 今天 ⋅ 0

SpringCloud Feign 传递复杂参数对象需要注意的地方

1.传递复杂参数对象需要用Post,另外需要注意,Feign不支持使用GetMapping 和PostMapping @RequestMapping(value="user/save",method=RequestMethod.POST) 2.在传递的过程中,复杂对象使用...

@林文龙 ⋅ 今天 ⋅ 0

如何显示 word 左侧目录大纲

打开word说明文档,如下图,我们发现左侧根本就没有目录,给我们带来很大的阅读障碍 2 在word文档的头部菜单栏中,切换到”视图“选项卡 3 然后勾选“导航窗格”选项 4 我们会惊奇的发现左侧...

二营长意大利炮 ⋅ 今天 ⋅ 0

智能合约编程语言Solidity之线上开发工具

工具地址:https://ethereum.github.io/browser-solidity/ 实例实验: 1.创建hello.sol文件 2.调试输出结果

硅谷课堂 ⋅ 今天 ⋅ 0

ffmpeg 视频格式转换

转 Mp4 格式 #> ffmpeg -i input.avi -c:v libx264 output.mp4#> ffmpeg -i input.avi -c:v libx264 -strict -2 output.mp4#> ffmpeg -i input.avi -c:v libx264 -strict -2 -s 1......

Contac ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部