Swift: включить или отключить ограничение ошибки - PullRequest
0 голосов
/ 23 июня 2018

Я создаю жест для представления, которое я назвал separatorView (на фотографии это средний черный вид).

Я использую метод ограничения и приоритеты, чтобы сделать это:

-centerConstraint = Это ограничение, позволяющее центрировать вид по горизонтали в X, приоритет = 1000

-rightConstant = Это ограничение связывает вид с краем правого экрана с нулевым шагом, приоритет = 999

-GaucheConstant = Это ограничение связывает вид с краем левого экрана с нулевым шагом, приоритет = 998

Когда я перетаскиваю этот вид влево, анимация продолжает перетаскиваться.

Проблема в том, что после завершения анимации я хочу возобновить просмотр и перетащить его влево. Центр обработки наличных денег равен нулю!

Я не могу найти решение, чтобы сделать все это общим, и я могу без проблем перемещать вид вправо или влево

Я знаю, что проблема связана с тем, что я отключаю ограничение

The photo

вот мой код:

@IBOutlet weak var sep: UIView!

@IBOutlet weak var constantGauche: NSLayoutConstraint!

@IBOutlet weak var constantDroite: NSLayoutConstraint!
@IBOutlet weak var centerConstraint: NSLayoutConstraint!

var startingConstant: CGFloat  = 0.0

var panGesture: UIPanGestureRecognizer?

override func viewDidLoad() {
    super.viewDidLoad()
    panGesture = UIPanGestureRecognizer(target: self, action: #selector(detectPan(recognizer:)))
    panGesture?.delaysTouchesBegan = false
    panGesture?.delaysTouchesEnded = false
    sep.addGestureRecognizer(panGesture!)
}

@objc func detectPan(recognizer: UIPanGestureRecognizer) {

    let translation = recognizer.translation(in: self.view)

    switch recognizer.state {
    case .began:
        self.startingConstant = self.centerConstraint.constant
    case .changed:
        self.centerConstraint.constant = self.startingConstant + translation.x
    case .ended:
        if translation.x > 0 {
            centerConstraint.isActive = false
            constantGauche.isActive = false
            constantDroite.isActive = true
            UIView.animate(withDuration: 0.5) {
                self.view.layoutIfNeeded()
            }
        }else{
            centerConstraint.isActive = false
            constantGauche.isActive = true
            constantDroite.isActive = false
            UIView.animate(withDuration: 0.5) {
                self.view.layoutIfNeeded()
            }
        }
    default:
        break
    }
}

1 Ответ

0 голосов
/ 24 июня 2018

Да, когда вы отключаете ограничение по центру, iOS удаляет его из ограничений представления и освобождает его, потому что на него больше нет сильной ссылки. @IBOutlet является ссылкой weak, которая устанавливается на nil, как только все сильные ссылки исчезнут. Таким образом, в следующий раз, когда вы получите доступ к ограничению центра, оно падает, потому что оно nil, а centerConstraint - это , неявно развернутое с !.

Вместо отключения ограничений измените их приоритеты:

  • Измените приоритет центрального ограничения на 999 в качестве начального значения. Вы получите сообщение об ошибке, если попытаетесь изменить приоритет требуемого ограничения в коде.
  • Понижение priority левого и центрального ограничений приведет к смещению sep вправо. Как только он попадет туда, вы можете вычислить новый constant для ограничения центра, а затем установить их приоритеты обратно на начальные значения.
  • Понижение priority правого и центрального ограничений приведет к смещению sep влево. Как только он попадет туда, вы можете вычислить новые constant для ограничения центра и затем установить их приоритеты обратно на начальные значения.

@objc func detectPan(recognizer: UIPanGestureRecognizer) {

    let translation = recognizer.translation(in: self.view)

    switch recognizer.state {
    case .began:
        self.startingConstant = self.centerConstraint.constant
    case .changed:
        self.centerConstraint.constant = self.startingConstant + translation.x
    case .ended:
        if translation.x > 0 {
            centerConstraint.priority = UILayoutPriority(rawValue: 750)
            constantGauche.priority = UILayoutPriority(rawValue: 750)
        } else {
            centerConstraint.priority = UILayoutPriority(rawValue: 750)
            constantDroite.priority = UILayoutPriority(rawValue: 750)
        }
        UIView.animate(withDuration: 0.5) {
            self.view.layoutIfNeeded()
        }
        print(sep.center.x - view.center.x)
        centerConstraint.constant = sep.center.x - view.center.x
        centerConstraint.priority = UILayoutPriority(rawValue: 999)
        constantGauche.priority = UILayoutPriority(rawValue: 998)
        constantDroite.priority = UILayoutPriority(rawValue: 998)
    default:
        break
    }
}

Вот изменения, запущенные в симуляторе:

Image of separator in the simulator

...