一个项目中很多地方都用到这种一个Icon 后面跟着一个TextField的 UI. 因为 Xcode 不支持这种界面上的重用.
而且就是是Copy and Paste也是有问题的,因为Copy进,View的约束并不会跟着走
为了避免重复劳动 ,就只要写一个简单的Custom View来实现了.
完整源代码见: https://gist.github.com/banxi1988/d31c7a41f29e7ddca728
@IBDesignable
- 自定义View的类声明没有此属性的话,Interface Builder 中的预览界面是显示不出来的.prepareForInterfaceBuilder()
方法来设置,只在开发时可用的初始值, 注意在开发时的,资源加载需要多写的代码.如:override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
let bundle = NSBundle(forClass: self.dynamicType)
let image = UIImage(named: "icon_locate", inBundle: bundle, compatibleWithTraitCollection: self.traitCollection)
iconImageView.image = image
textField.text = "大学英语四级"
backgroundColor = UIColor.lightGrayColor()
}
instrinsicContentSize()
一般的实现逻辑的,遍历,组合,比较,求和.override func intrinsicContentSize() -> CGSize {
let iconSize = iconImageView.intrinsicContentSize()
let textSize = textField.intrinsicContentSize()
let width = padding.left + iconSize.width + iconPadding + textSize.width + padding.right
let height = padding.top + max(iconSize.height, textSize.height) + padding.bottom
return CGSize(width: width, height: height)
}
设置AutoLayout约束时,值得注意:
4.1 除非确实需要,不要忘记调用 iconImageView.setTranslatesAutoresizingMaskIntoConstraints(false)
4.2 设置好contentHuggingPriority,和 contentResistancePriority
如这里,在整个UI控制伸长时,先让textField
变长
textField.setContentHuggingPriority(240, forAxis: UILayoutConstraintAxis.Horizontal)
当组合中的子控件的内容发生了变化,正确做法是应该调用:
invalidateIntrinsicContentSize()
@IBInspectable
属性目前不建议使用,用一次卡一次
如果取消不用了,记得将IB中控件属性的这些自定义属性,删除.
PS:
问: 标题是基于组合的Custom View 那还有基于其他的吗?
答: 有,还有基于继承,然后主要是 自定义 drawRect
方法,或者自定义 CALayer
的
当然,更多是两者都基于.
希望对大家有用.
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.