【问题标题】:Cannot find superview while adding constrains programmatically?以编程方式添加约束时找不到超级视图?
【发布时间】:2017-02-12 11:08:28
【问题描述】:

在尝试以编程方式添加约束时参考此问题Making a custom UIView subview that fills its superview

我正在使用下面的代码以编程方式添加两个约束;但是,我收到“无法解析约束格式”的错误状态,因为相关视图没有超级视图。

private func setupDownView(view: UIView) {
    let downView = try? DownView(frame: view.bounds, markdownString: "")
    downView!.translatesAutoresizingMaskIntoConstraints = false
    let viewsDict = ["view": downView!]
    downView!.addConstraint(NSLayoutConstraint.constraints(
        withVisualFormat: "V:|-0-[view]-0-|",
        options: [],
        metrics: nil,
        views: viewsDict)[0])
    downView!.addConstraint(NSLayoutConstraint.constraints(
        withVisualFormat: "H:|-0-[view]-0-|",
        options: [],
        metrics: nil,
        views: viewsDict)[0])
    view.addSubview(downView!);
}

view auto 添加到其子视图后是否会成为超级视图?

我尝试在通过addSubviewaddConstraint 之前设置约束之前添加视图,但我收到错误“视图层次结构没有为约束做好准备”。

setupDownView在以下两个地方被调用,

@IBOutlet weak var cardTags: UIView! {didSet { setupDownView(view: cardTags)}}
@IBOutlet weak var cardContent: UIView! {
    didSet {
        setupDownView(view: cardContent)
        let tap = UILongPressGestureRecognizer(
            target: self,
            action: #selector(QuizViewController.tapDownHandler)
        )
        tap.minimumPressDuration = 0
        cardContent.addGestureRecognizer(tap)
    }
}

【问题讨论】:

  • 你能在下面提供一个答案作为那些有类似问题的参考吗?
  • 我添加了我的评论作为答案。

标签: ios swift autolayout


【解决方案1】:

需要在视图位于层次结构之后添加约束。所以addSubview 调用必须在之前 addConstraint 调用。

还要确保在其父视图上调用addConstraint,而不是downView,并且添加从constraintsWithVisualFormat: 返回的所有约束,而不仅仅是第一个。

private func setupDownView(view: UIView) {
    let downView = try? DownView(frame: view.bounds, markdownString: "")
    downView!.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(downView!);

    let viewsDict = ["view": downView!]
    view.addConstraints(NSLayoutConstraint.constraints(
        withVisualFormat: "V:|-0-[view]-0-|",
        options: [],
        metrics: nil,
        views: viewsDict))
    view.addConstraints(NSLayoutConstraint.constraints(
        withVisualFormat: "H:|-0-[view]-0-|",
        options: [],
        metrics: nil,
        views: viewsDict))

    view.layoutIfNeeded()
}

【讨论】:

  • 谢谢。我试过你的代码,但我的downViews 消失了。 :(
  • 完全没有错误,只是不再显示在视图上。
  • Storyboard中superview有限制吗?
【解决方案2】:

从 iOS 8 开始,您不必确定要向哪个视图添加约束,只需激活它们即可。对于个别约束,只需将.isActive 设置为true。要激活整个约束数组,请使用 NSLayoutConstraint.activate() 便捷方法。

对于您的代码,而不是这样做:

view.addConstraints(NSLayoutConstraint.constraints(
    withVisualFormat: "V:|-0-[view]-0-|",
    options: [],
    metrics: nil,
    views: viewsDict))

你会使用:

NSLayoutConstraint.activate(NSLayoutConstraint.constraints(
    withVisualFormat: "V:|-0-[view]-0-|",
    options: [],
    metrics: nil,
    views: viewsDict))

这是可行的,因为约束已经知道它们引用的是哪个或哪些视图,并且 CocoaCocoa Touch 可以在视图层次结构中找出适当的视图来添加约束,这可能会很棘手,具体取决于视图的相关方式(例如兄弟姐妹、父/子、其他)。

同样的注意事项也适用于此。您需要确保视图在激活约束之前位于视图层次结构中,否则会出错。所以,在激活约束之前执行.addSubview

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 2017-04-22
    相关资源
    最近更新 更多