【问题标题】:Having issues with activating constraints programmatically and getting errors以编程方式激活约束并出现错误时遇到问题
【发布时间】:2018-05-18 17:55:27
【问题描述】:

昨晚我在这里发布了一个问题,我使用故事板来设置约束。我决定用锚测试它并以编程方式进行约束。

我收到此错误:

由于未捕获的异常“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

现在没有出现同样的错误,但是,我无法在 mainbackgroundview 上设置 backgroundview1。

我将其添加为子视图:

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

我现在做错了什么?

【问题讨论】:

  • 您也错过了在所有视图中设置 yourView.translatesAutoresizingMaskIntoConstraints=false。还为约束设置 .isActive=true。
  • 试过了。还是不行:(
  • "mainbackgroundview.addSubview(backgroundview1)"。这会在 "mainbackgroundview" 上添加 "backgroundView1" 。因此,“backgroundView1”的约束应该参考“mainbackgroundview”,而不是视图。

标签: ios uiview autolayout storyboard constraints


【解决方案1】:

在 setupViews() 函数中,您正在添加约束但未将它们设置为活动状态。这是一个可以成功添加的示例锚约束:

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

尝试在每个约束的末尾添加 .isActive。

此外,您还可以添加相关的锚约束,例如:topAnchor、bottomAnchor、widthAnchor、heightAnchor、leadingAnchor 等。尝试简化您的约束。

【讨论】:

  • 我已经更新了帖子。我没有收到同样的错误,但似乎无法为我放置在 mainbackgroundview 顶部的视图设置约束。请检查一下!
  • 你好兄弟,我刚刚检查了你的代码。您以错误的顺序实施它。只有在将视图添加到主视图后才能添加约束。在 viewdidload() 结束时调用 setupviews()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 2020-04-20
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多