Невозможно активировать ограничение с помощью якорей при добавлении текстового поля - PullRequest
0 голосов
/ 27 сентября 2019

Некоторое время назад я начал создавать свои экраны через раскадровку.

Недавно я убедился, что делаю это программно.

В настоящее время я сталкиваюсь со следующей ошибкой:

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

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

}

Я создал функцию для привязки своих элементов в 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
        }


    }
}

Кроме того, я удалил Манифест сцены приложения в Info.plist.

Я хочу, чтобы мой проект поддерживал будущие версии iOS, начиная с 13.0.Тем не менее я не хочу использовать новый фреймворк SwiftUI.

Есть ли какие-то конкретные вещи, на которые стоит обратить внимание (например, Scene Delegate)?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Textfield не удалось получить родительский вид, когда вы добавляли его ограничение.Ниже код работает для меня.Я передал текущее представление в качестве параметра методу 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
         }
      }
}
0 голосов
/ 27 сентября 2019

Вам нужно изменить это

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
}

на это

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
}()

В текущей версии emailTextField является вычисляемым свойством, поэтому каждый раз, когда вы обращаетесь к нему, компилятор создает новый экземпляр(работает как функция, а не переменная).

...