具有动态约束的IBDesignable视图:渲染时错位的子项

时间:2017-08-02 16:38:58

标签: ios swift xcode xcode-storyboard ibdesignable

我正在尝试构建(以编程方式)新视图并使用IBDesignable属性来简化此过程并在故事板中显示视图而不是白色矩形。

这是一个包含两个子视图的类:UILabelUIImageView。我将它们动态添加到父视图中,并为它们设置一些约束:

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: $0,
                options: .directionLeadingToTrailing,
                metrics: nil,
                views: views)
        }        

        NSLayoutConstraint.activate(constraints)
    }

}

这些还不完美,但至少 - 在模拟器中显示: cell in simulator

但是当我在storyboard builder中重新加载视图时,我看到了: cell in storyboard

如您所见,故事板中未强制执行约束,并且未显示图像。你知道怎么解决这个问题吗?或者,甚至可以在故事板和模拟器中获得相同的图片?

  

解决方案:请查看@DonMag的答案。它允许查看我期待的结果(见附图)。

enter image description here

1 个答案:

答案 0 :(得分:2)

请勿为您的可设计视图设置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中的图片:

    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"))
    ...