Рамка UIButton не меняется, если ее панорамировать - PullRequest
0 голосов
/ 29 мая 2018

Вот изображение простого приложения, которое я пытаюсь сделать

В приложении есть распознаватель жестов панорамирования для центральной фиолетовой кнопки, кнопка при перемещении, если она пересекается с любымиз 4 оранжевых кнопок фиолетовая кнопка анимирует и перемещается в пределах кнопки, которую она пересекает, в противном случае она возвращается к исходной начальной позиции, то есть к центру.

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

Я предполагаю, что это что-то связанное с Auto Layout, что яотсутствует, потому что если я удаляю ограничения на центральной фиолетовой кнопке, рамка обновляется каждый раз правильно, если я перемещаюсь.

Кто-нибудь может объяснить, что я должен иметь в виду при анимации с ограничениями

Вот мой код для обработки жеста панорамирования:

@objc func handleCenterRectPan(_ pannedView: UIPanGestureRecognizer) {

        let fallBackAnimation = UIViewPropertyAnimator(duration: 0.3, dampingRatio: 0.5) {
                if self.button1.frame.intersects(self.centerRect.frame) {
                    self.centerRect.center = self.button1.center
                } else if self.button2.frame.contains(self.centerRect.frame) {
                    self.centerRect.center = self.button2.center
                } else if self.button3.frame.contains(self.centerRect.frame) {
                    self.centerRect.center = self.button3.center
                } else if self.button4.frame.contains(self.centerRect.frame) {
                    self.centerRect.center = self.button4.center
                } else {
                    // no intersection move to original position
                    self.centerRect.frame = OGValues.oGCenter
                }
        }

        switch pannedView.state {
        case .began:
            self.centerRect.center = pannedView.location(in: self.view)
        case .changed:
            print("Changed")
            self.centerRect.center = pannedView.location(in: self.view)
        case .ended, .cancelled, .failed :
            print("Ended")
            fallBackAnimation.startAnimation();
            //snapTheRectangle()
        default:
            break
        }
    }

1 Ответ

0 голосов
/ 29 мая 2018

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

Итак, вы можете сделать следующее:

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

ИЛИ

Создайте IBoutlet для ограничений и установите для .isActive значение false при перетаскивании пользователя и сделайте его истинным, если он отсутствует внутри других кнопок, и обновите UpdateLayoutIfNeeded,так что он вернется в исходное положение.(хороший подход)

@IBOutlet var horizontalConstraints: NSLayoutConstraint!            
@IBOutlet var verticalConstraints: NSLayoutConstraint!

//make active false as the user is dragging the view
horizontalConstraints.isActive = false
verticalConstraints.isActive = false
self.view.layoutIfNeeded()

//make it true again if its not inside any of the other views 
horizontalConstraints.isActive = true
verticalConstraints.isActive = true
self.view.layoutIfNeeded()

ИЛИ

Обновите constraints.constants для горизонтальных и вертикальных ограничений, когда пользователь перемещает представление (не очень хороший подход), и снова обнулите его, если это не таквнутри любого другого представления

//make it true again if its not inside any of the other views 
horizontalConstraints.constant = change in horizontal direction
verticalConstraints..constant =  change in vertical direction
self.view.layoutIfNeeded()

Редактировать Как вы сказали, ограничения равны нулю после установки isActive = false, потому что на самом деле isActive делает, добавляет и удаляет эти ограничения, как говорит Apple Doc

Активация или деактивация ограничения вызывает addConstraint ( :) и removeConstraint ( :) для представления, которое является ближайшим общим предком элементов, управляемых этим ограничением.Используйте это свойство вместо вызова addConstraint ( :) или removeConstraint ( :) напрямую.

Таким образом, создание строгой ссылки для ограничений решает проблему, но я думаю, что установка строгой ссылки на IBOutelet не очень хорошая идея, и лучше добавлять и удалять ограничения программным путем.проверить этот вопрос, освобождая ограничения

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