SnapKit выдает ошибку, когда вы пытаетесь задать ограничения для UIView

У меня есть UIView, который подключен к моему контроллеру представления как IBOutlet. Я назначил экземпляр класса AnimationView этому свойству в своем методе ViewDidLoad и установил для него ограничения с помощью 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. Создайте представление-заполнитель в раскадровке и добавьте его как IBOutlet к владельцу вашего файла (убедитесь, что вы ввели AnimationView в качестве его класса на крайней правой панели).
  2. Программно создайте представление анимации и добавьте его к непосредственному суперпредставлению.
  3. Дайте этому анимационному представлению тот же кадр, что и замещающему виду animationView.frame = placeholderView.frame
  4. Дайте ограничения, которые вы хотите, для представления заполнителя (placeholderView.snp.makeConstraints { (make) in ... })

Теперь вы подключили свое представление, созданное программно, к представлению-заполнителю в раскадровке. Ваше программное представление изменит размер с размером представления-заполнителя.


person Junsu Kim    schedule 29.06.2021    source источник
comment
Пожалуйста, разместите код в виде текста.   -  person Sweeper    schedule 29.06.2021


Ответы (2)


Во-первых, в вашем коде вы не вызываете super.viewDidLoad(), это очень важно, и tbh может быть причиной проблемы.

Во-вторых, измените @IBOutlet на переменную, поэтому 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)
    }
}

Если вы хотите сохранить его в раскадровке:

@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.

person Ayrton CB    schedule 29.06.2021
comment
Можете ли вы создать тот же вид анимации, но с раскадровкой? с IBOutlet.. - person Junsu Kim; 29.06.2021
comment
Только что обновил мой ответ, вы можете, вам просто нужно установить собственный класс в представлении, если вы используете Xcode 12, затем выберите представление, а затем нажмите кнопку, которая выглядит как газета на правой панели, вы должны затем см. поле Custom Class - person Ayrton CB; 29.06.2021
comment
Потратил часы, пытаясь понять, что я сделал не так, и я не установил класс моего IBOutlet на AnimationView на крайней правой панели в раскадровке. Большое спасибо! - person Junsu Kim; 30.06.2021

1- Вы не должны менять тип представления

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

тогда

animationV = AnimationView()
view.addSubview(animationV)

2- Добавьте ограничения centerX/Y в animationV

Кстати, вам не нужно устанавливать представление в IB, сделать его только программным и дать ему все подходящие ограничения.

person Sh_Khan    schedule 29.06.2021
comment
Дело в том, что я пытаюсь создать пользовательский интерфейс с помощью раскадровки, и если я сделаю это представление в коде, я не смогу увидеть его в своей раскадровке. - person Junsu Kim; 29.06.2021
comment
Почему вы должны увидеть программный вид в IB? - person Sh_Khan; 29.06.2021
comment
Кстати, вы можете назначить имя класса для просмотра в IB AnimationView - person Sh_Khan; 29.06.2021
comment
Просто чтобы узнать, где он находится на экране, чтобы я мог добавить больше элементов пользовательского интерфейса под анимациюView. Если вы добавляете представление программно, как вы добавляете к нему ограничения в раскадровке для других представлений? - person Junsu Kim; 29.06.2021
comment
добавьте его в IB, а затем свяжите его как выход и создайте представление анимации в коде и задайте ему те же ограничения, что и вид выхода, что означает верх, лево, право и низ, как в ответе - person Sh_Khan; 29.06.2021