Возникли проблемы с программной активацией ограничений и получением ошибок

Прошлой ночью я разместил здесь вопрос, где я использовал раскадровки для установки ограничений. Я решил протестировать его с якорями и сделать ограничения программно.

Я получаю эту ошибку:

Завершение работы приложения из-за необработанного исключения «NSGenericException», причина: «Невозможно активировать ограничение с якорями и потому, что у них нет общего предка. Ссылается ли ограничение или его привязки на элементы в разных иерархиях представлений? Это незаконно.

Я знаю, что это связано с тем, что представления не являются подвидами определенного другого представления, однако я проверял это много раз и не знаю, что делать.

вот код:

import UIKit
import CoreData
class editViewController: UIViewController {

let screenSize: CGRect = UIScreen.main.bounds
let moContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var editnotes: addednotes?




let mainbackgroundview: UIView =
{
    let view = UIView()
    view.backgroundColor = .black
    view.alpha = 0.3

    return view
}()


let backgroundview1: UIView =
{
    let view = UIView()
    view.backgroundColor = .purple

    return view
}()


let edittasktextview1: UITextView = {
    let tv = UITextView()
    tv.backgroundColor = .black
    return tv
}()

    let cancelButton : UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Cancel", for: .normal)
        button.addTarget(self, action: #selector(handleCancelButton), for: 
.touchUpInside)
    return button
}()

let doneButton1 : UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("Done", for: .normal)
    button.addTarget(self, action: #selector(handleDoneButton), for: .touchUpInside)
    return button
}()



@objc func handleCancelButton() {

    edittasktextview1.endEditing(true)
    dismiss(animated: true, completion: nil)
}


@objc func handleDoneButton()
{
    dismiss(animated: true, completion: nil)

    if edittasktextview1.text.isEmpty == true
    {
        moContext.delete(editnotes!)
    }
    else
    {
        editnotes?.sNote = edittasktextview1.text
    }
    var error: NSError?
    do {
        // Save The object

        try moContext.save()
        print("SAVED")
    } catch let error1 as NSError {
        error = error1
    }

    edittasktextview1.endEditing(true)

}



override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NotificationID"), object: nil)

}
override func viewDidAppear(_ animated: Bool) {
    //add something here
   // edittasktextview.becomeFirstResponder()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.navigationBar.tintColor = UIColor.white
    navigationItem.title = "Edit Tasks"
    edittasktextview1.text = editnotes?.sNote
    backgroundview1.backgroundColor = editnotes?.sPriorityColor
    edittasktextview1.backgroundColor = .clear
    setupviews()
    //adding gesture to the background view to dismiss keyboard
    let dismisskeyboardgesture = UITapGestureRecognizer()
    dismisskeyboardgesture.addTarget(self, action: #selector(dismisskeyboard))


    let maskPath = UIBezierPath.init(roundedRect: self.backgroundview1.bounds, byRoundingCorners:[.topLeft, .topRight], cornerRadii: CGSize.init(width: 20.0, height: 0))
    let maskLayer = CAShapeLayer()
    maskLayer.frame = self.backgroundview1.bounds
    maskLayer.path = maskPath.cgPath
    self.backgroundview1.layer.mask = maskLayer
     view.backgroundColor = .clear


    //view.addGestureRecognizer(dismisskeyboardgesture)
    view.addSubview(mainbackgroundview)
   mainbackgroundview.addSubview(backgroundview1)
// view.addSubview(backgroundview1)
    backgroundview1.addSubview(edittasktextview1)
    backgroundview1.addSubview(cancelButton)
    backgroundview1.addSubview(doneButton1)
}

    @objc func dismisskeyboard()
   {
    edittasktextview1.endEditing(true)
   }


func setupviews()
{
   mainbackgroundview.anchorToTop(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
    backgroundview1.anchor(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 45, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)

    edittasktextview1.anchor(view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, topConstant: 40, leftConstant: 8, bottomConstant: 0, rightConstant: 8, widthConstant: 0, heightConstant: 150)

    cancelButton.anchor(edittasktextview1.bottomAnchor, left: nil, bottom: nil, right: view.rightAnchor, topConstant: 18, leftConstant: 0, bottomConstant: 0, rightConstant: 8, widthConstant: 40, heightConstant: 30)

   doneButton1.anchor(edittasktextview1.bottomAnchor, left: view.leftAnchor, bottom: nil, right: nil, topConstant: 18, leftConstant: 8, bottomConstant: 0, rightConstant: 0, widthConstant: 40, heightConstant: 30)


}

}

Помощь будет оценена по достоинству, так как я застрял в этой проблеме почти 18 часов :(

ОБНОВЛЕНИЕ №1

Однако теперь я не получаю ту же ошибку, я не могу установить backgroundview1 на mainbackgroundview.

Я добавляю его как подвид:

mainbackgroundview.addSubview(backgroundview1)

В setupviews() я помещаю ограничение так:

 NSLayoutConstraint.activate([
        backgroundview1.leftAnchor.constraint(equalTo: mainbackgroundview.leftAnchor, constant: 0),
        backgroundview1.rightAnchor.constraint(equalTo: mainbackgroundview.rightAnchor, constant: 0),
        backgroundview1.bottomAnchor.constraint(equalTo: mainbackgroundview.bottomAnchor, constant: 0),
        backgroundview1.topAnchor.constraint(equalTo: mainbackgroundview.topAnchor, constant: 45)

        ])

Тем не менее, я не могу поставить backgroundview1 на mainbackgroundview. Однако на симуляторе отображается mainbackgroundview.

Я добавляю mainbackgroundview вот так:

 NSLayoutConstraint.activate([
        mainbackgroundview.leftAnchor.constraint(equalTo: view.leftAnchor),
        mainbackgroundview.rightAnchor.constraint(equalTo: view.rightAnchor),
        mainbackgroundview.topAnchor.constraint(equalTo: view.topAnchor),
        mainbackgroundview.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])

Что я сейчас делаю не так?


person Osama Naeem    schedule 05.12.2017    source источник
comment
вы также пропустили установку yourView.translatesAutoresizingMaskIntoConstraints=false во всех ваших представлениях. Также установите .isActive=true для ограничений.   -  person Tushar Sharma    schedule 05.12.2017
comment
попробовал это. До сих пор не работает :(   -  person Osama Naeem    schedule 05.12.2017
comment
mainbackgroundview.addSubview (фоновый вид1). Это добавляет backgroundView1 к mainbackgroundview. Таким образом, ограничения для backgroundView1 должны относиться к mainbackgroundview, а не к представлению.   -  person Tushar Sharma    schedule 05.12.2017


Ответы (1)


В функции setupViews() вы добавляете ограничения, но не устанавливаете их как активные. Это пример ограничения привязки, которое можно успешно добавить:

myView.bottomAnchor.constraint(equalTo: view.topAnchor,
   constant: 8).isActive=true 

Попробуйте добавить .isActive в конце каждого ограничения.

Кроме того, вы можете добавить соответствующие ограничения привязки, например: topAnchor, bottomAnchor, widthAnchor, heightAnchor, LeadAnchor и т. д. Попробуйте упростить свои ограничения.

person Amrit Sidhu    schedule 05.12.2017
comment
Я обновил пост сейчас. Я не получаю ту же ошибку, но не могу установить ограничение для представления, которое я разместил поверх основного фона. Пожалуйста, проверьте это! - person Osama Naeem; 05.12.2017
comment
Эй, брат, я только что проверил твой код. Вы реализуете его в неправильном порядке. Ограничения могут быть добавлены только после того, как вы добавите вид в основной вид. Вызовите setupviews() в конце viewdidload(). - person Amrit Sidhu; 05.12.2017