Как программно отключить ограничение при анимации - PullRequest
0 голосов
/ 18 января 2019

У меня есть вид с фиксированной шириной, привязанный слева.Я хочу, чтобы этот вид анимировался (двигаясь слева направо), закрепляя его справа (таким образом удаляя левый якорь).Как мне это сделать?

Я попытался установить приоритет, но не уверен в синтаксисе.Я также пытался отключить ограничение, но это не сработало.

fileprivate func sparkle() {
    let sparkleView = UIView()
    sparkleView.backgroundColor = UIColor.yellow
    sparkleView.alpha = 0.5
    addSubview(sparkleView)
    sparkleView.translatesAutoresizingMaskIntoConstraints = false
    sparkleView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    sparkleView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    layoutIfNeeded()
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
    sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    UIView.animate(withDuration: 2, animations: {
        self.layoutIfNeeded()
    }) { (_) in
        sparkleView.removeFromSuperview()
    }
}

В настоящее время ограничение ширины нарушается, поскольку мы назначаем левый и правый якорь.

enter image description here

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35   (active)>

- РЕДАКТИРОВАТЬ -

Я попытался создать переменную экземпляра для хранения ограничения.

let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true

Затем я попыталсяизменить приоритет

leftCons.priority = UILayoutPriorityDefaultLow

Однако это вызывает ошибку

'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported.  You passed priority 250 and the existing priority was 1000.'

Вместо этого мне нужно просто установить его как неактивный (из ответов)

leftCons.active = false

- Исправьте код, если вы заинтересованы .. -

fileprivate func sparkle() {
    let sparkleView = UIView()
    sparkleView.backgroundColor = UIColor.yellow
    sparkleView.alpha = 0.5
    addSubview(sparkleView)
    sparkleView.translatesAutoresizingMaskIntoConstraints = false
    sparkleView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    sparkleView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
    let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
    leftCons.isActive = true
    layoutIfNeeded()
    leftCons.isActive = false
    sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    UIView.animate(withDuration: 0.5, animations: {
        self.layoutIfNeeded()
    }) { (_) in
        sparkleView.removeFromSuperview()
    }
}

1 Ответ

0 голосов
/ 18 января 2019

Вам нужно создать переменную

var leftCon:NSLayoutConstraint!

затем измените его, ваша проблема - каждая строка создает новое ограничение

sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true

примечание: выше 3 ограничений создают конфликт, так как представление не может быть закреплено влево и вправо одновременно с ограничением ширины, поэтому вы видите конфликт перерыв => NSLayoutConstraint: 0x6000020b8eb0 UIView: 0x7fc846d551d0.width == 15,35 (активный)

независимо от активного назначения, поэтому те

sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work 
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work

находятся на лету и не изменяют созданное ограничение, поэтому

leftCon = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCon.isActive = true

Относительно этого крушения

'Изменение приоритета от обязательного к отсутствию установленного ограничения (или наоборот) не поддерживается

вам нужно установить приоритет перед активацией

leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...