IBDesignable View with Dynamic Constraints:渲染时错位的子元素
IBDesignable View with Dynamic Constraints: Misplaced Children when Rendering
我正在尝试(以编程方式)构建一个新视图并使用 IBDesignable
属性来简化此过程并在情节提要中显示视图而不是白色矩形。
这里是一个 class,有两个子视图:UILabel
和 UIImageView
。我正在将它们动态添加到父视图并为它们设置几个约束:
import UIKit
@IBDesignable
class ChoiceView: UIView {
enum ChoiceState {
case empty, chosen
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViewForState(.empty)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViewForState(.empty)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
}
private func setupViewForState(_ state: ChoiceState) {
guard case .empty = state else { return } // single case for now
let placeholder = UILabel()
let choiceImage = UIImageView(image: UIImage(named: "plus_small"))
placeholder.text = "None"
placeholder.textAlignment = .right
choiceImage.contentMode = .center
let constraintFormats = [
"H:|-0-[placeholder]-10-[choice(50)]-0-|",
"V:|-0-[placeholder]-0-|",
"V:|-0-[choice]-0-|"
]
let views = ["placeholder": placeholder, "choice": choiceImage]
translatesAutoresizingMaskIntoConstraints = false
placeholder.translatesAutoresizingMaskIntoConstraints = false
choiceImage.translatesAutoresizingMaskIntoConstraints = false
addSubview(placeholder)
addSubview(choiceImage)
let constraints = constraintFormats.flatMap {
NSLayoutConstraint.constraints(
withVisualFormat: [=10=],
options: .directionLeadingToTrailing,
metrics: nil,
views: views)
}
NSLayoutConstraint.activate(constraints)
}
}
这些还不完美,但至少 - 在模拟器中显示:
但是当我在 Storyboard Builder 中重新加载视图时,我看到了这个:
如您所见,情节提要中没有强制执行约束,也没有显示图像。你知道怎么解决吗?或者,是否有可能在故事板和模拟器中获得相同的图片?
Solution: Please look at @DonMag answer. It allows to see result I was expecting (see picture attached).
不要为您的可设计视图 本身设置 translatesAutoresizingMaskIntoConstraints = false
。
let views = ["placeholder": placeholder, "choice": choiceImage]
// don't do this one
//translatesAutoresizingMaskIntoConstraints = false
placeholder.translatesAutoresizingMaskIntoConstraints = false
choiceImage.translatesAutoresizingMaskIntoConstraints = false
addSubview(placeholder)
addSubview(choiceImage)
此外,要在 IB 中查看您的 "choice" 图片:
let theBundle = Bundle(for: type(of: self))
let choiceImage = UIImageView(image: UIImage(named: "plus_small", in: theBundle, compatibleWith: self.traitCollection))
//
//let choiceImage = UIImageView(image: UIImage(named: "plus_small"))
...
我正在尝试(以编程方式)构建一个新视图并使用 IBDesignable
属性来简化此过程并在情节提要中显示视图而不是白色矩形。
这里是一个 class,有两个子视图:UILabel
和 UIImageView
。我正在将它们动态添加到父视图并为它们设置几个约束:
import UIKit
@IBDesignable
class ChoiceView: UIView {
enum ChoiceState {
case empty, chosen
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViewForState(.empty)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViewForState(.empty)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
}
private func setupViewForState(_ state: ChoiceState) {
guard case .empty = state else { return } // single case for now
let placeholder = UILabel()
let choiceImage = UIImageView(image: UIImage(named: "plus_small"))
placeholder.text = "None"
placeholder.textAlignment = .right
choiceImage.contentMode = .center
let constraintFormats = [
"H:|-0-[placeholder]-10-[choice(50)]-0-|",
"V:|-0-[placeholder]-0-|",
"V:|-0-[choice]-0-|"
]
let views = ["placeholder": placeholder, "choice": choiceImage]
translatesAutoresizingMaskIntoConstraints = false
placeholder.translatesAutoresizingMaskIntoConstraints = false
choiceImage.translatesAutoresizingMaskIntoConstraints = false
addSubview(placeholder)
addSubview(choiceImage)
let constraints = constraintFormats.flatMap {
NSLayoutConstraint.constraints(
withVisualFormat: [=10=],
options: .directionLeadingToTrailing,
metrics: nil,
views: views)
}
NSLayoutConstraint.activate(constraints)
}
}
这些还不完美,但至少 - 在模拟器中显示:
但是当我在 Storyboard Builder 中重新加载视图时,我看到了这个:
如您所见,情节提要中没有强制执行约束,也没有显示图像。你知道怎么解决吗?或者,是否有可能在故事板和模拟器中获得相同的图片?
Solution: Please look at @DonMag answer. It allows to see result I was expecting (see picture attached).
不要为您的可设计视图 本身设置 translatesAutoresizingMaskIntoConstraints = false
。
let views = ["placeholder": placeholder, "choice": choiceImage]
// don't do this one
//translatesAutoresizingMaskIntoConstraints = false
placeholder.translatesAutoresizingMaskIntoConstraints = false
choiceImage.translatesAutoresizingMaskIntoConstraints = false
addSubview(placeholder)
addSubview(choiceImage)
此外,要在 IB 中查看您的 "choice" 图片:
let theBundle = Bundle(for: type(of: self))
let choiceImage = UIImageView(image: UIImage(named: "plus_small", in: theBundle, compatibleWith: self.traitCollection))
//
//let choiceImage = UIImageView(image: UIImage(named: "plus_small"))
...