不幸的是,在不指定其大小值(即width 和height)的情况下,添加UIView 并没有流畅的方法。
说到自动布局,你有两个选项,可能你也已经知道了。 1)你应该设置UIView's的大小值,或者2.你设置其他UI对象的大小,以便自动布局可以理解UIView的大小。
以编程方式来说,在创建UIView 对象时,如果您不提供框架,则不会显示。虽然这可能是一个可以放置在任何大小的任何点的解决方案,但当您使用 xib 或情节提要时,它可能并不理想,因为这些接口上存在差距,这也可能会混淆开发。
我的想法包括同时使用intrinsicContentSize 和IBDesignable。为此,我做了一个小演示,您可以在下面找到此代码。我将分享2个例子,一个继承自UILabel,另一个继承自UIView,以便我更容易地展示intrinsicContentSize的用法。
下面是UIView 一个。
import UIKit
@IBDesignable class UIDemoView: UIView {
func setup() {
layer.cornerRadius = frame.height / 5
clipsToBounds = true
}
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
self.setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.setup()
}
override var intrinsicContentSize: CGSize {
let newWidth = 100
let newHeight = 100
let newSize = CGSize(width: newWidth, height: newHeight)
return newSize
}
}
下面是 UILabel 一个。
import UIKit
@IBDesignable class UIDemoLabel: UILabel {
func setup() {
layer.cornerRadius = frame.height / 2
clipsToBounds = true
textAlignment = .center
}
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
self.setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.setup()
}
override var intrinsicContentSize: CGSize {
let superSize = super.intrinsicContentSize
let newWidth = superSize.width + superSize.height
let newHeight = superSize.height
let newSize = CGSize(width: newWidth, height: newHeight)
return newSize
}
}
这是自动布局的输出
我故意展示了这两个对象的约束,所以你可以检查我是否理解正确。它们都只有 2 个约束:顶部对齐和居中对齐。
UILabels 有自己的intrinsicContentSize,所以在覆盖它们时,我们可能会使用他们已经给出的intrinsicContentSize 作为参考,作为我们想做的任何事情的指导。 UIViews intrinsicContentSize 没有设置,因此我们必须找到一种方法来给它们特定的大小。不确定,我猜测UILabelintrinsicContentSize 的实现,逻辑很可能与文本的大小有关。您可以像上面的代码一样简单地传递常量,或者您可以使用任何自定义逻辑来提供CGFloats。
只是我的一个想法:尽管我提供了这个解决方案,但我不是IBDesignables 的粉丝。从我的角度来看,他们减慢了开发速度,因为它有缺陷。因此,老实说,我宁愿 1. 将 UIView 对象放在 xibs 和 storyboards 上,2. 将其类从 UIView 更改为自定义 UIView 类,3. 设置其约束,4. 设置以编程方式从其IBOutlet 中获取剩余属性。这更像是一种传统的方式,虽然:)
希望对您有所帮助!