[英]Unable to activate constraint with anchors while adding a textfield
A while ago I started creating my screens via the storyboard.不久前,我开始通过 storyboard 创建我的屏幕。
Recently I have been convinced doing it programmatically.最近,我确信以编程方式进行。
Currently I am running into the following error:目前我遇到以下错误:
Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors and because they have no common ancestor.
由于未捕获的异常“NSGenericException”而终止应用程序,原因:“无法使用锚激活约束,因为它们没有共同的祖先。 Does the constraint or its anchors reference items in different view hierarchies?
约束或其锚点是否引用不同视图层次结构中的项目? That's illegal.'
这是非法的。
import UIKit
class ViewController: UIViewController {
var emailTextField: UITextField {
let tf = UITextField()
tf.placeholder = "email";
tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
tf.borderStyle = .roundedRect
tf.font = UIFont.systemFont(ofSize: 14)
return tf
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(emailTextField)
emailTextField.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 40, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40)
}
}
I have created a function to anchor my elements in Extensions.swift:我创建了一个 function 来将我的元素锚定在 Extensions.swift 中:
import UIKit
extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, right: NSLayoutXAxisAnchor?, paddingTop: CGFloat, paddingLeft: CGFloat, paddingBottom: CGFloat, paddingRight: CGFloat, width: CGFloat, height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top {
self.topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
}
if let left = left {
self.leftAnchor.constraint(equalTo: left, constant: paddingLeft).isActive = true
}
if let bottom = bottom {
self.bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
}
if let right = right {
self.rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true
}
if width != 0 {
widthAnchor.constraint(equalToConstant: width).isActive = true
}
if height != 0 {
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
}
In addition, I deleted the Application Scene Manifest in Info.plist
.另外,我删除了
Info.plist
的 Application Scene Manifest。
I want my project to support the upcoming iOS versions starting at 13.0.我希望我的项目支持从 13.0 开始即将推出的 iOS 版本。 Nevertheless I don't want to use the new framework SwiftUI.
不过我不想使用新框架 SwiftUI。
Are there any specific things to watch out for (eg Scene Delegate)?是否有任何需要注意的具体事项(例如场景代表)?
Thank you in advance!先感谢您!
You need to change this你需要改变这个
var emailTextField: UITextField {
let tf = UITextField()
tf.placeholder = "email";
tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
tf.borderStyle = .roundedRect
tf.font = UIFont.systemFont(ofSize: 14)
return tf
}
into this进入这个
var emailTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "email";
tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
tf.borderStyle = .roundedRect
tf.font = UIFont.systemFont(ofSize: 14)
return tf
}()
In current version emailTextField
is computed property, so, every time you access it compiler create a new instance (it works like function, not variable).在当前版本
emailTextField
是计算属性,因此,每次访问它时,编译器都会创建一个新实例(它的工作方式类似于 function,而不是变量)。
Textfield was unable to get its parent view while you were adding its constraint.添加约束时,Textfield 无法获取其父视图。 Below code works for me.
下面的代码对我有用。 I passed current view as a param to anchor() method and add emailTextField as a subview there.
我将当前视图作为参数传递给 anchor() 方法,并在那里添加 emailTextField 作为子视图。
class ViewController: UIViewController {
var emailTextField:UITextField = {
let tf = UITextField()
tf.placeholder = "email";
tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
tf.borderStyle = .roundedRect
tf.font = UIFont.systemFont(ofSize: 14)
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
emailTextField.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 40, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40, view:view)
}
}
extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, right: NSLayoutXAxisAnchor?, paddingTop: CGFloat, paddingLeft: CGFloat, paddingBottom: CGFloat, paddingRight: CGFloat, width: CGFloat, height: CGFloat, view:UIView) {
translatesAutoresizingMaskIntoConstraints = false
view.addSubview(self)
if let top = top {
self.topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
}
if let left = left {
self.leftAnchor.constraint(equalTo: left, constant: paddingLeft).isActive = true
}
if let bottom = bottom {
self.bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
}
if let right = right {
self.rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true
}
if width != 0 {
widthAnchor.constraint(equalToConstant: width).isActive = true
}
if height != 0 {
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.