swift UIView 构造函数

2021-10-21  本文已影响0人  我会回来的

基本声命周期 

1 初始化  -》 2 约束和布局 -〉 3绘制渲染 -》 4 销毁

init(coder:)/init(frame:) // 【初始化】可视化加载/代码初始化

          init(frme: CGRect): 代码初始化时调用。

          init(coder: NSCoder): xib 或者 stroryboard 加载时调用。

updateConstraints() // 【约束更新】可选, 基于 AutoLayout 布局时调用

layoutSubviews() // 【子视图布局】调用一次或者多次,基于 AutoLayout 一般会调用两次及以上

draw(_:) // 【绘制】

draw(_:in:)

布局约束周期

1  基于frame坐标系布局的,在layoutSubViews方法中设置frame。

2 不建议在updateConstraints() 里添加约束,建议在动作发生时修改约束值,而不是在该方法。 

3  Auto layout 的布局过程是 updateConstraints -》 layoutSubViews -〉 draw ,这三步不是单向的。如果layout 的过程中改变了constrait ,会触发update constraints,进行新一轮的迭代。

// 重点: 重写updateConstraints() 一定要在最后调用super.updateConstraints()

1 纯代码自定义View   

// 代码初始化

override init(frame: CGRect) { super.init(frame: frame) commonInit() }

// 用在xib 和 storyboard 初始化

required init?(coder: NSCoder) { super.init(coder: coder) commonInit() }

添加 View 和设置控件

fileprivate func commonInit() {

    addSubview(imageView)    // 没有设置frame 大小

    label.textAlignment = .center

    label.font = UIFont.systemFont(ofSize: 14)

    label.textColor = .green

    addSubview(label)     // 没有设置frame大小

}

2  布局子控件 

重写layouSubviews()并设置子控件位置大小

override func layoutSubviews() {

    super.layoutSubviews()

    let imageViewW: CGFloat = 60

    let imageViewX = (bounds.width-60)/2

    imageView.frame = CGRect(x: imageViewX, y: 8,width: imageViewW, height: imageViewW)

    let labelY = imageViewW + 8 + 8

    label.frame = CGRect(x: 0, y: labelY, width: bounds.width, height: 17)

}

2  自定义   XIB    UIView 

代码如下:

class CustomXibView: UIView {

    var contentView:UIView!

    class func instantiateFromNib() -> CustomXibView {

        returnBundle.main.loadNibNamed("CustomXibView", owner:nil, options:nil)?.firstas!CustomXibView

    }

 //初始化时将xib中的view添加进来

    overrideinit(frame:CGRect) {

        super.init(frame: frame)

        contentView = CustomXibView.instantiateFromNib()

        initialSetup()

    }

 //初始化时将xib中的view添加进来

    requiredinit?(coder  aDecoder:NSCoder) {

        super.init(coder: aDecoder)

        contentView = CustomXibView.instantiateFromNib()

        initialSetup()

    }

    //用约束在xib里设置frame

    // 1 Controller->loadView ,Controller->viewDidLoad 两个方法后调用

    // 2 初始化时没有设置rect,不被自动调用。

    // 3 控制器设置值给View

    // 4 设置contentMode为UIViewContentModeRedraw,每次设置或更改frame时候调用draw

    // 5 直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。

    overridefuncdraw(_rect:CGRect) {

        super.draw(rect)

        //设置一些子视图的固定属性

    }

 //初始化默认属性配置

    func  initialSetup(){

        //值的属性

    }

  //布局相关设置

   // 1、init初始化不会触发layoutSubviews。

   // 2、addSubview会触发layoutSubviews。

   // 3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。

   // 4、滚动一个UIScrollView会触发layoutSubviews。

   // 5、旋转Screen会触发父UIView上的layoutSubviews事件。

   // 6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。

   // 7、直接调用setLayoutSubviews。

    override func layoutSubviews() {

        super.layoutSubviews()

        // 布局相关的一些设置

    }

   /* 当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的 awakeFromNib函数来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象是执行awakeFromNib  先init 再awakeFromNib()(一般做初始化操作)。*/

    override func awakeFromNib() {

        super.awakeFromNib()

    }

}

// 外部调用

let xibView = CustomXibView.instantiateFromNib()

xibView.frame=CGRect(x:10, y:30, width:200, height:40)

self.view.addSubview(xibView)

纯代码

 overrideinit(frame:CGRect) 

 requiredinit?(coder  aDecoder:NSCoder)

纯xib 

awakeFromNib()

上一篇下一篇

猜你喜欢

热点阅读