Mengalami masalah dengan mengaktifkan batasan secara terprogram dan mendapatkan kesalahan

Tadi malam saya memposting pertanyaan di sini di mana saya menggunakan storyboard untuk menetapkan batasan. Saya memutuskan untuk mengujinya dengan jangkar dan melakukan batasan secara terprogram.

Saya mendapatkan kesalahan ini:

Menghentikan aplikasi karena pengecualian 'NSGenericException' yang tidak tertangkap, alasan: 'Tidak dapat mengaktifkan batasan dengan jangkar dan karena mereka tidak memiliki nenek moyang yang sama. Apakah batasan atau jangkarnya merujuk pada item dalam hierarki tampilan berbeda? Itu ilegal.'

Saya tahu ini ada hubungannya dengan pandangan yang bukan merupakan subview dari pandangan tertentu lainnya, namun saya telah memeriksanya berkali-kali dan saya tidak tahu harus berbuat apa.

ini kodenya:

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)


}

}

Bantuan akan dihargai, karena saya terjebak pada masalah ini selama hampir 18 jam :(

PEMBARUAN #1

Namun, tidak mendapatkan kesalahan yang sama sekarang, saya tidak dapat mengatur tampilan latar belakang1 di tampilan latar belakang utama.

Saya menambahkannya sebagai subview:

mainbackgroundview.addSubview(backgroundview1)

Di setupviews() saya menempatkan batasan seperti ini:

 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)

        ])

Tetap saja saya tidak mendapatkan backgroundview1 untuk ditempatkan di mainbackgroundview. mainbackgroundview muncul di simulator.

Saya menambahkan mainbackgroundview seperti ini:

 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)
        ])

Apa yang saya lakukan salah sekarang?


person Osama Naeem    schedule 05.12.2017    source sumber
comment
Anda juga melewatkan menyetel yourView.translatesAutoresizingMaskIntoConstraints=false di semua tampilan Anda. Juga menyetel .isActive=true untuk batasan.   -  person Tushar Sharma    schedule 05.12.2017
comment
mencobanya. Masih tidak bekerja :(   -  person Osama Naeem    schedule 05.12.2017
comment
tampilan latar belakang utama.addSubview(tampilan latar belakang1). Ini menambahkan backgroundView1 pada mainbackgroundview . Jadi batasan untuk backgroundView1 harus mengacu pada mainbackgroundview , dan bukan tampilan.   -  person Tushar Sharma    schedule 05.12.2017


Jawaban (1)


Dalam fungsi setupViews() Anda menambahkan batasan tetapi tidak mengaturnya sebagai aktif. Ini adalah contoh batasan jangkar yang berhasil ditambahkan:

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

Coba tambahkan .isActive di akhir setiap batasan Anda.

Selain itu, Anda dapat menambahkan batasan jangkar yang relevan misalnya: topAnchor, bottomAnchor, widthAnchor, heightAnchor, leadAnchor, dll. Coba sederhanakan batasan Anda.

person Amrit Sidhu    schedule 05.12.2017
comment
Saya telah memperbarui postingan sekarang. Saya tidak mendapatkan kesalahan yang sama tetapi sepertinya tidak dapat menetapkan batasan untuk tampilan yang saya tempatkan di atas tampilan latar belakang utama. Silakan periksa! - person Osama Naeem; 05.12.2017
comment
Hai saudara, saya baru saja memeriksa kode Anda. Anda menerapkannya dalam urutan yang salah. Batasan hanya dapat ditambahkan setelah tampilan Anda ditambahkan ke tampilan utama. Panggil setupviews() di akhir viewdidload(). - person Amrit Sidhu; 05.12.2017