【问题标题】:IBDesignable View with Dynamic Constraints: Misplaced Children when Rendering具有动态约束的 IBDesignable 视图:渲染时放错位置的子项
【发布时间】:2017-08-02 16:38:57
【问题描述】:

我正在尝试(以编程方式)构建一个新视图并使用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)
    }

}

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

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

如您所见,情节提要中未强制执行约束,并且未显示图像。你知道怎么解决吗?或者,是否有可能在故事板和模拟器中获得相同的图片?


解决方案:请看@DonMag 的回答。它可以看到我期望的结果(见附图)。

【问题讨论】:

  • 由于 IB 是一个 design-time 工具,你不能期望 code 会在其中处理。所以,不,这是不可能的。
  • 我明白了,但是你看,标签显示正确,标题设置在代码中。因此,我虽然可以为UIImage 做同样的事情。
  • @devforfu 你检查我的答案了吗?
  • 这不是我看到的。您的第一个屏幕截图 - 在模拟器中完成,正在处理您的编码约束 - 看起来不错。但是第二个屏幕截图 - 不处理代码的屏幕截图?带有“无”的标签位于左上角,而不是图像的左侧。并且图像不可见因为设置它的代码没有被执行。 (我猜如果您在 IB 中设置图像,您会在与标签相同的位置看到它。但这取决于您在 IB 中还做了什么。)
  • 很高兴您找到了解决方案!保存此以供将来参考。 (我基本上是一个只懂代码的人。现在。)

标签: ios swift xcode xcode-storyboard ibdesignable


【解决方案1】:

不要为您的 Designable 视图本身设置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"))
    ...

【讨论】:

  • 完全有效的解决方案。图像和标签都正确显示和对齐。
  • 为什么会出现问题?,帮我解决了,谢谢!
猜你喜欢
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多