iOS-IBDesignable/IBInspectable动态改变控件属性

转在于 http://www.jianshu.com/p/826027b93706

Xcode7.3,swift2.2
Storyboard凭借其方便直观等优点,已经越来越多用于项目开发中.这里我来介绍一下刚学到的一个技巧.

1.问题来源


IBDemo01.png


当UI设计师设计的界面中有这样的控件,你会怎么做.
1.使用代码
在不允许使用storyboard或xib时,只能用代码,在run时才能看到效果
2.使用storyboard,拖控件,设置圆角,边框
仍旧需要使用代码来实现,在run时才能看到效果.而且拖一个控件只是为了设置其边框、圆角,会增加代码量,不简洁.
3.使用Runtime Attributes


IBDemo02.png


不用拖控件写代码设置,但是KeyPath中设置属性没有提示,对于习惯于提示的我,总是先在代码中写好,再复制到KeyPath中,且run时才能看到效果
layer.borderColor是CGColor类型,如果直接设置颜色,是没有效果的,需要在CALayer中扩展一个自定义属性

extension CALayer {
    public var borderUIColor:UIColor? {
        set(newValue) {
            self.borderColor = newValue?.CGColor
        }
        get {
            return UIColor(CGColor: self.borderColor!)
        }
    }
}

使用自定义属性borderUIColor设置边框颜色


IBDemo03.png


5.使用IBDesignableIBInspectable动态改变.

2.使用IBDesignable和IBInspectable动态改变

1.创建类

创建一个类MMButton,继承于UIButton
class前加关键字,@IBDesignable

@IBDesignable
class MMButton: UIButton {
}

增加自定义属性,并且在属性前加关键字@ IBInspectable,重写didSet方法

@IBDesignable
class MMButton: UIButton {
    //圆角
    @IBInspectable var cornerRadius:CGFloat = 0.0 {
        didSet {
            self.layer.cornerRadius = cornerRadius
        }
    }
    //边框宽度
    @IBInspectable var borderWidth:CGFloat = 0.0 {
        didSet {
            self.layer.borderWidth = borderWidth
        }
    }
    //边框颜色
    @IBInspectable var borderColor:UIColor = UIColor() {
        didSet {
            self.layer.borderColor = borderColor.CGColor
        }
    }
}
2.创建控件

向storyboard/xib中的view上拖一个UIButton控件,并修改class为刚才新建的类MMButton
现在可以在Attributes Inspector中看到MMButton中设置的属性


IBDemo04.png

这时改变属性值,就可以实时看到UI效果


IBDemo08.gif

3.OC用法

1..h文件声明

在.h文件中声明属性,在属性中加关键字IBInspectable

#import <UIKit/UIKit.h>
@interface MMButton : UIButton
@property (nonatomic, assign) IBInspectable CGFloat connerRadius;
@property (nonatomic, assign) IBInspectable CGFloat borderWidth;
@property (nonatomic, assign) IBInspectable UIColor *borderColor;
@end
2..m文件实现,重写set方法

在.m文件中,添加关键字IB_DESIGNABLE

#import "MMButton.h"
IB_DESIGNABLE
@implementation MMButton
- (void)setConnerRadius:(CGFloat)connerRadius {
    _connerRadius = connerRadius;
    self.layer.cornerRadius = _connerRadius;
    self.layer.masksToBounds = YES;
}
- (void)setBorderWidth:(CGFloat)borderWidth {
    _borderWidth = borderWidth;
    self.layer.borderWidth = _borderWidth;
}
- (void)setBorderColor:(UIColor *)borderColor {
    _borderColor = borderColor;
    self.layer.borderColor = _borderColor.CGColor;
}
@end

4.为项目设计属于自己的"UIKit"库

1.常用控件
UIView, UILabel, UIButton, UIImageView: layer.cornerRadius, layer.borderColor, layer.borderWidth
UILabel: UIEdgeInsets
UITextField: leftView, rightView
2.UIView/UIButton/UIImageView

这三个控件可以设置常用的属性,

self.layer.cornerRadius
self.layer.borderColor
self.layer.borderWidth
3.UILabel
self.layer.cornerRadius
self.layer.borderColor
self.layer.borderWidth

除了以上三个常用属性,还可以添加边距

@IBInspectable var insetTop:CGFloat = 0 {
        didSet {
        }
    }
    @IBInspectable var insetLeft:CGFloat = 0 {
        didSet {
        }
    }
    @IBInspectable var insetBottom:CGFloat = 0 {
        didSet {
        }
    }
    @IBInspectable var insetRight:CGFloat = 0 {
        didSet {
        }
    }
    override func drawTextInRect(rect: CGRect) {
        super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(insetTop, insetLeft, insetBottom, insetRight)))
    }

IBDemo07.png
4.UITextField

设置textField.leftViewtextField.rightView

@IBDesignable
class MMTextField: UITextField {
    //************* leftView *************
    @IBInspectable var leftImage:UIImage = UIImage() {
        didSet {
            self.leftViewMode = .Always
            let imageView = UIImageView(image: leftImage)
            imageView.clipsToBounds = true
            imageView.contentMode = .ScaleAspectFit
            //为了看一下leftView的大小(rect),实际使用时不用设置
            imageView.backgroundColor = UIColor.redColor()
            self.leftView = imageView
        }
    }
    @IBInspectable var leftViewWidth:CGFloat = 0 {
        didSet {
            self.leftView?.frame = CGRectMake(0, 0, leftViewWidth, leftViewHeight)
        }
    }
    @IBInspectable var leftViewHeight:CGFloat = 0 {
        didSet {
            self.leftView?.frame = CGRectMake(0, 0, leftViewWidth, leftViewHeight)
        }
    }
    //************* rightView ************
    @IBInspectable var rightImage:UIImage = UIImage() {
        didSet {
            self.rightViewMode = .Always
            self.rightView?.clipsToBounds = true
            let imageView = UIImageView(image: rightImage)
            imageView.contentMode = .ScaleAspectFit
            self.rightView?.backgroundColor = UIColor.greenColor()
            self.rightView = imageView
        }
    }
    @IBInspectable var rightViewWidth:CGFloat = 0 {
        didSet {
            self.rightView?.frame = CGRectMake(0, 0, rightViewWidth, rightViewHeight)
        }
    }
    @IBInspectable var rightViewHeight:CGFloat = 0 {
        didSet {
            self.rightView?.frame = CGRectMake(0, 0, rightViewWidth, rightViewHeight)
        }
    }
    //************* textRect *************
    override func textRectForBounds(bounds: CGRect) -> CGRect {
        var rect = bounds
        rect.origin.x += leftViewWidth
        rect.size.width -= (leftViewWidth+rightViewWidth)
        return rect
    }
    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        var rect = bounds
        rect.origin.x += leftViewWidth
        rect.size.width -= (leftViewWidth+rightViewWidth)
        return rect
    }
}

IBDemo08.png


leftViewrightView的背景色是为了演示视图大小(rect),实际使用时,去掉颜色


IBDemo09.png


可以方便设置这种登录界面

5.注意点

修改属性之后,可以看到在 User Defined Runtime Attributes 中会自动添加属性


IBDemo05.png


由于英语不好,拼错了单词cornerRadius,出于程序员的强迫症,必须把他改过来.改完后,再设置属性,发现原来的属性仍旧存在.需要把原来的属性删掉


IBDemo06.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值