viewWillTransitionToSize导致非旋转视图控制器调整大小并重新定位

时间:2015-10-14 18:31:28

标签: ios rotation viewwilltransitiontosize swift2.1

很多人讨论了模仿原生iOS相机应用程序的技巧(UI元素在设备旋转时就地旋转)。我实际上在here之前问了一个关于它的问题。大多数人都会锁定UI的方向,但是只对要旋转的元素强制进行转换。这样可行,但元素不会与您在原生iOS应用中看到的平滑动画一起转动,并且会导致一些问题。具体来说,我的界面的一部分允许用户在不离开此界面的情况下进行共享,但是当共享视图被轮换时,它会偏离中心。所以我想找到一种不同的方法来做到这一点。

我找到了Apple's 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 个答案:

答案 0 :(得分: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()实现相同类型的接口(参见my question about it here)。我相信这种方法是一种更简洁的方法来创建这种类型的接口,但我还没有能够在没有崩溃的情况下使其工作。