【问题标题】:SnapKit throws an error when you try to give constraints to UIView当您尝试为 UIView 提供约束时,SnapKit 会引发错误
【发布时间】:2021-09-11 15:20:41
【问题描述】:

我有一个作为 IBOutlet 连接到我的视图控制器的 UIView。我在 ViewDidLoad 方法中为该属性分配了一个 AnimationView 类实例,并使用 animationView.snp.makeConstraints { (make) in make.width.equalTo(view).multipliedBy(0.5) } 对其设置了约束

但是当我运行我的项目时,我收到一条错误消息,提示“约束或其锚点是否引用了不同视图层次结构中的项目?这是非法的”

我不知道为什么会收到此错误消息。谁能解释我做错了什么?

以下是我的项目图片:

以及正文中的源代码:

import UIKit
import SnapKit
import Lottie

class ViewController: UIViewController {

    @IBOutlet var myView: UIView!
    
    override func viewDidLoad() {
        myView = AnimationView()
        myView.snp.makeConstraints { (make) in
            make.width.equalTo(view).multipliedBy(0.5)
            make.height.equalTo(view).multipliedBy(0.5)
        }
    }
    
}

更新:

我如何通过以下步骤解决此问题:

  1. 在 Storyboard 中创建一个占位符视图并将其作为 IBOutlet 添加到文件的所有者(确保在最右侧面板中键入 AnimationView 作为其类)。
  2. 以编程方式创建动画视图并将其添加到其直接超级视图中。
  3. 为此动画视图提供与占位符视图相同的帧 animationView.frame = placeholderView.frame
  4. 为占位符视图提供所需的约束 (placeholderView.snp.makeConstraints { (make) in ... })

现在,您将通过编程创建的视图连接到 Storyboard 中的占位符视图。您的程序化视图将随着占位符视图的大小而改变大小。

【问题讨论】:

  • 请将您的代码以文本形式发布。

标签: ios swift lottie snapkit


【解决方案1】:

1- 你不应该改变视图的类型

 @IBOutlet var myView:UIView!
 var animationV:AnimationView!

然后

animationV = AnimationView()
view.addSubview(animationV)

2- 将 centerX/Y 约束添加到animationV

顺便说一句,您不必在 IB 中设置视图,仅将其设为程序化视图并为其提供所有合适的约束

【讨论】:

  • 问题是我正在尝试使用 Storyboard 创建 UI,如果我在代码中创建此视图,我将无法在我的 Storyboard 中看到它
  • 为什么要在 IB 中看到程序化视图?
  • 顺便说一句,您可以指定类名以在 IB AnimationView 中查看
  • 只是想知道它在屏幕上的位置,以便我可以在动画视图下方添加更多 UI 元素。如果以编程方式添加视图,如何在 Storyboard 中为其他视图添加约束?
  • 将其添加到 IB 中,然后将其链接为插座,并在代码中创建您的动画视图,并为其赋予与插座视图相同的约束,如答案中的顶部、左侧、右侧和底部
【解决方案2】:

首先,在您的代码中,您没有调用 super.viewDidLoad(),这非常重要,并且可能会导致问题。

其次,将@IBOutlet改为var,所以var myView: AnimationView!

第三,在添加约束之前,您可能需要将myView 添加到您的视图或其父视图中,例如view.addSubView(myView)

var myView: AnimationView!

override func viewDidLoad() {
    super.viewDidLoad()
    myView = AnimationView()
    view.addSubView(myView)

    myView.snp.makeConstraints { (make) in
        make.width.equalTo(view).multipliedBy(0.5)
        make.height.equalTo(view).multipliedBy(0.5)
        make.centerY.equalTo(self.view)
        make.centerX.equalTo(self.view)
    }
}

如果您想将其保留在 Storyboard 中:

@IBOutlet weak var myView: AnimationView!

override func viewDidLoad() {
    super.viewDidLoad()

    myView.snp.makeConstraints { (make) in
        make.width.equalTo(view).multipliedBy(0.5)
        make.height.equalTo(view).multipliedBy(0.5)
        make.centerY.equalTo(self.view)
        make.centerX.equalTo(self.view)
    }
}

要将其保留为情节提要,您需要将情节提要中的视图类设置为AnimationView

【讨论】:

  • 你能用 Storyboard 创建同样的动画视图吗?与 IBOutlet..
  • 刚刚更新了我的答案,你可以,你只需要在视图上设置一个自定义类,如果你使用 Xcode 12 然后选择视图然后点击有点像报纸的按钮在最右侧的面板中,您应该会看到一个 Custom Class 字段
  • 花了几个小时试图找出我做错了什么,但我没有在 Storyboard 的最右侧面板中将 IBOutlet 的类设置为 AnimationView。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多