viewWillTransitionToSize заставляет невращающийся контроллер представления изменять размеры и перемещать

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

Я нашел ссылку на образец Apple AVCam, который положил мне начало здесь. Я новичок в этом, но мне уже удалось преобразовать его из Obj-C в Swift. Ниже приведен ключевой элемент того, что я сейчас использую:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        //Code here performs animations during the rotation

        let deltaTransform: CGAffineTransform = coordinator.targetTransform()
        let deltaAngle: CGFloat = atan2(deltaTransform.b, deltaTransform.a)
        var currentRotation: CGFloat = self.nonRotatingView.layer.valueForKeyPath("transform.rotation.z") as! CGFloat

        // Adding a small value to the rotation angle forces the animation to occur in a the desired direction, preventing an issue where the view would appear to rotate 2PI radians during a rotation from LandscapeRight -> LandscapeLeft.
        currentRotation += -1 * deltaAngle + 0.0001;
        self.nonRotatingView.layer.setValue(currentRotation, forKeyPath: "transform.rotation.z")

        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            print("rotation completed");
            // Code here will execute after the rotation has finished
            // Integralize the transform to undo the extra 0.0001 added to the rotation angle.
            var currentTransform: CGAffineTransform = self.nonRotatingView.transform
            currentTransform.a = round(currentTransform.a)
            currentTransform.b = round(currentTransform.b)
            currentTransform.c = round(currentTransform.c)
            currentTransform.d = round(currentTransform.d)
            self.nonRotatingView.transform = currentTransform
    })

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

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

Проблема в том, что размер невращающегося изображения изменяется, и все становится неуместным, когда я поворачиваю устройство из портретной в альбомную или наоборот. Как мне это исправить?

1 ответ

Я получил это работает (хотя это заняло у меня гораздо больше времени, чем следовало бы). Мне нужно было установить параметры ширины и высоты для невращающегося представления, чтобы удалить его во время сборки, а затем добавить следующее к viewDidLoad():

let nonRotatingWidth = nonRotatingView.widthAnchor.constraintEqualToConstant(UIScreen.mainScreen().bounds.width)
let nonRotatingHeight = nonRotatingView.heightAnchor.constraintEqualToConstant(UIScreen.mainScreen().bounds.height)
nonRotatingView.addConstraints([nonRotatingWidth, nonRotatingHeight])

При этом используется новый синтаксис ограничений Swift 2, который относительно лаконичен и удобен для чтения.

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

Другие вопросы по тегам