Custom UIView

最近项目需要自定义一个 UIView,虽然不是第一次做,但是还是出现了很多问题,其中最严重是的获取的 self.bounds 是不对。

Debug 能力真的需要提高了,调试了很久,还是靠断点,逐个对比 bounds 才知道问题所在。

http://stackoverflow.com/questions/29763818/making-a-custom-uiview-subview-that-fills-its-superview

这一篇解释的很清楚,我自己混淆了几种方法的使用,还忘记了手动设置 frame 时,还忘了layoutSubviews()。以前可能是宽高确定或根据 UIScreen 来的计算的,一直没出现问题。

  1. Use Auto Layout
    • Interface Builder
    • Programmatically
  2. Manual Layout
    • Resizing Masks
    • Layout Subviews

关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}

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

private func setupViews() {

let view = UIView(frame: CGRectZero)
view.setTranslatesAutoresizingMaskIntoConstraints(false)
super.init(frame: frame)
let viewsDict = ["view": view]
addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[view]-0-|", options: .allZeros, metrics: nil, views: viewsDict))
addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[view]-0-|", options: .allZeros, metrics: nil, views: viewsDict))
addSubview(view)

}

原因

viewDidLoad 时获取的size 可能是错误的。

viewDidLoad

The view controller has obtained its view. See the discussion earlier in this chapter of how a view controller gets its view. Recall that this does not mean that the view is in the interface or even that it has been given its correct size.