iOS 自定义View

作者: smalldu | 来源:发表于2017-04-20 22:02 被阅读1595次

    在日常开发中,一个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以及动画等,如果有兴趣下次再讲。

    相关文章

      网友评论

      本文标题:iOS 自定义View

      本文链接:https://www.haomeiwen.com/subject/spqrzttx.html