虽然说,在很多情况下,使用Storyboard或者xib开发具有方便快捷的优点,但是,如果使用不熟练的话,将会面临许多巨大无比、令人沮丧的坑。为了尽快踩到这些天坑,我还是决定用Storyboard和xib来搞一搞。
我准备搭建下面这样的界面,因此考虑用xib来创建顶部明星打榜。用xib的好处是,布局好第一个明星板块,其它两个直接使用Ctrl+D,再进行总体布局就可以了。如果是使用纯代码的话……不敢想!不敢想!
因为那个顶部的明星打榜是跟随tableView一起滚动的,因此我的想法是,先修改tableView的contentInset
,让它整体往下移动kBillboardHeight
个高度,然后再创建一个相同高度的自定义控件,最后再把它加到tableView上面补上:
// MARK: - 先把tableView往下挪动kBillboardHeight个单位
// 调整tableView的contentInset
tableView.contentInset = UIEdgeInsetsMake(kBillboardHeight, 0, 0, 0)
// MARK: - 然后再创建一个高度为kBillboardHeight的billboard
/// 顶部的"明星打榜动态"
lazy var billboard: RecommentBillboard = {
// 调用类方法,通过xib来创建一个RecommendBillboard实例
let billboard = RecommentBillboard.loadFromNib()
// 设置billboard的frame
billboard.frame = CGRect(x: 0, y: -kBillboardHeight, width: kScreenWidth, height: kBillboardHeight)
return billboard
}()
// 添加billboard到tableView上面
tableView.addSubview(billboard)
嗯,常规操作,应该就是这样!因为我在使用纯代码创建的时候就是这么操作的,都搞了好多遍了,应该不会出问题:
嗯?!!!!what the f**k!这明显不对劲儿啊?我明明给了很大的量的,为毛出来一个发育不全的?难道是我加载xib的代码不对?
class RecommentBillboard: UIView {
/// 通过xib来创建一个RecommentBillboard实例
class func loadFromNib() -> RecommentBillboard {
return Bundle.main.loadNibNamed("RecommentBillboard", owner: nil, options: nil)?.first as! RecommentBillboard
}
}
仔细看了好一阵子,也没发现什么毛病。但是为什么出来的东西就是不像自己亲生的呢?那个高度是我设的吗?带着疑惑,还是用同样的的姿势,我又用纯代码搞了一遍:
lazy var billboard2: UIView = {
// 调用类方法,通过xib来创建一个RecommendBillboard实例
let billboard = UIView()
billboard.frame = CGRect(x: 0, y: -kBillboardHeight, width: kScreenWidth, height: kBillboardHeight)
billboard.backgroundColor = .yellow
return billboard
}()
// 添加billboard到tableView上面
tableView.addSubview(billboard)
下面这个yellow才是亲生的!通过xib加载控件的代码没问题,而且控件也加载出来了,但是为什么明明一毛一样的数据,最后却出来两种不同的效果呢?
经过查找资料,最后才发现原来是Auto Layout和Autoresizing的锅。只需要像下面这样,去掉Use Auto Layout前面的勾(后面两个也会跟着取消),然后去掉Autoresizing里面多余的约束,只保留与父控件顶部和左边的约束就行了:
换回通过xib加载控件的代码,然后运行程序,你就会发现,一切都是你想要的结果。详细代码参见SwiftProjects,Objective-C代码参见ObjCProjects。