iOS 自定义View

在日常开发中,一个App会有很多模块中的小模块相差不多。这时候我们就需要考虑公用 -- 自定义View , 这样就可以避免很多重复的代码。

有哪些需要考虑的

  • 首先要考虑不同的调用,纯代码的方式或者Xib 、Storyboard的方式都要可以使用
  • 要有一定的可定制化 ,也就是暴露出来的属性
  • 使用起来简单

实例

例如有这样的 View 在不同的地方有用到。

截图

很简单的一个视图,图片加文字加边框。

首先,新建一个UIView的子类ImageTextView , 在class前面添加open关键字 (我们要做成公用的)

删除drawRect相关方法,将下面代码复制进去

 public override init(frame: CGRect) {
    super.init(frame: frame)
    #if !TARGET_INTERFACE_BUILDER  // 非interfabuilder环境下
    // 如果是从代码层面开始使用Autolayout,需要对使用的View的translatesAutoresizingMaskIntoConstraints的属性设置为false
      translatesAutoresizingMaskIntoConstraints = false
    #endif
    prepareView()
  }
  
  required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    prepareView()
  }
  
  // 布局
  func prepareView(){

  }

init?(coder:) 是从Xib或者Storyboard创建的时候会调用。 其他看注释咯 - _ -

UIImageView添加一个扩展,方便创建UIImageView对象

extension UIImageView {
  class func configuredImageView() -> UIImageView {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.clipsToBounds = true
    imageView.contentMode = .scaleAspectFill
    return imageView
  } 
}

回到ImageTextView中声明图片和文本的变量

fileprivate let imageView = UIImageView.configuredImageView()  
fileprivate lazy var textLabel = UILabel()

prepareView中对图片和文本进行布局

// 布局
  func prepareView(){
    textLabel.translatesAutoresizingMaskIntoConstraints = false
    textLabel.font = UIFont.systemFont(ofSize: CGFloat(textSize))
    
    addSubview(imageView)
    addSubview(textLabel)
    imageView.setContentCompressionResistancePriority(1000, for: .horizontal )
    NSLayoutConstraint.activate([
        imageView.leftAnchor.constraint(equalTo: leftAnchor, constant:10 ) ,
        imageView.centerYAnchor.constraint(equalTo: centerYAnchor) ,
        textLabel.leftAnchor.constraint(equalTo: imageView.rightAnchor , constant:2 ) ,
        textLabel.centerYAnchor.constraint(equalTo: centerYAnchor) ,
        textLabel.rightAnchor.constraint(equalTo: rightAnchor, constant:-10)
      ])
    
    layer.borderColor = UIColor.lightGray.cgColor
    layer.borderWidth = 0.5
    layer.cornerRadius = 3
  }

这里的布局方法是iOS 9 开始支持的API , 当然你也可以使用SnapKit

为了使我们的View可以在 InterfaceBuilder 中使用,在类前面使用注解 @IBDesignable
并暴露出可以自定义的属性

extension ImageTextView{
  
  @IBInspectable
  open var image:UIImage?{
    get{
      return imageView.image
    }
    set{
      imageView.image = newValue
    }
  }
  
  @IBInspectable
  open var text:String?{
    get{
      return textLabel.text
    }
    set{
      textLabel.text = newValue ?? ""
    }
  }
  
  @IBInspectable
  open var textColor:UIColor? {
    get{
      return textLabel.textColor
    }
    set{
      textLabel.textColor = newValue
    }
  }
}

在变量声明下面在加上字体大小

//  这里使用 textSize 是因为 IBInspectable 暂时还不支持 UIFont
  @IBInspectable
  open var textSize:UInt = 17 {
    didSet{
      textLabel.font = UIFont.systemFont(ofSize: CGFloat(textSize))
    }
  }

这块由于暂时不支持UIFont所以使用了UInt

我们还可以在InterfaceBuilder渲染前做一些事情

 override open func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    // interface builder 渲染前执行  不会影响真正运行效果
    layer.borderColor = UIColor.lightGray.cgColor
    layer.borderWidth = 0.5
    layer.cornerRadius = 3
  }

到这里,这个自定义View就算完成了,看下载Storyboard中的使用吧

随便拖一个UIView
修改Class属性

截图

保存后就可以看到这些属性了

截图

设置完成后 InterfaceBuilder 立刻会渲染出来

截图

这里是我随便设了几个属性

截图

有了这个自定义的View,那么在任何地方有相似效果,我们只需要像拖UILabel一样把他拖出来简单的设置下属性就好了(也可以通过手写代码创建)。当然,这只是一个简单的demo,并没有涉及到事件Layer以及动画等,如果有兴趣下次再讲。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容