Как правило, такое поведение при просмотре видов, возвращающихся в исходное положение, является результатом сочетания (а) использования ограничений автоматического размещения; и (б) делать что-то, что вызывает ограничения, которые будут применены повторно. Этот процесс повторного применения ограничений иногда может быть вызван самым безобидным действием пользовательского интерфейса. В итоге, вместо того, чтобы беспокоиться о том, что вызвало повторное применение ограничений, лучше всего просто убедиться, что ваши представления останутся там, где вы хотите, даже после того, как это произойдет.
Одним из решений является обновление transform
представлений, а не center
, например ::
var originalTransform: CGAffineTransform!
@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
originalTransform = gesture.view!.transform
case .changed, .ended:
let translation = gesture.translation(in: gesture.view)
gesture.view?.transform = originalTransform.translatedBy(x: translation.x, y: translation.y)
default:
break
}
}
Этот метод работает, но также чувствует себя немного хрупким, в зависимости от плохо документированного поведения между ограничениями и преобразованиями представления.
Другой, более надежный, но немного более сложный подход заключается в настройке свойства constant
ограничений. Например, вы можете сами создать @IBOutlet
ссылки для ограничений, подключить эти выходы в IB, а затем распознаватель жестов может соответствующим образом обновить их свойства constant
:
@IBOutlet weak var horizontalConstraint: NSLayoutConstraint!
@IBOutlet weak var verticalConstraint: NSLayoutConstraint!
private var originalHorizontalConstant: CGFloat!
private var originalVerticalConstant: CGFloat!
@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
originalHorizontalConstant = horizontalConstraint.constant
originalVerticalConstant = verticalConstraint.constant
case .changed, .ended:
let translation = gesture.translation(in: gesture.view)
horizontalConstraint.constant = originalHorizontalConstant + translation.x
verticalConstraint.constant = originalVerticalConstant + translation.y
default:
break
}
}
Теперь, ясно, что если вы потенциально перетаскиваете разные виды вокруг этого, это может немного запутаться, но, надеюсь, вышеприведенное иллюстрирует основную идею.
Какой бы метод вы ни применяли, основная идея состоит в том, чтобы избегать обновления center
или frame
представления, положение которого определяется ограничениями автоматической компоновки.