3

A lot of people have discussed techniques for mimicking the native iOS camera app (where the UI elements pivot in-place as the device rotates). I actually asked a question about it before here. Most people have you lock the orientation of the UI, but then force a transformation on just the elements that you want to pivot. This works, but the elements don't pivot with the smooth animations you see in the native iOS app and it leads some issues. Specifically, part of my interface allows users to share without leaving this interface, but when the sharing view gets rotated, it comes out off-center. So I wanted to find a different way to do this.

I found a link to Apple's AVCam sample, which got me off to a start here. I'm new to this stuff, but I managed to convert it from Obj-C to Swift already. Below is the key element of what I'm currently using:

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)
}

I then have separate view controllers for icons that do the same transformation in the opposite direction. The icons actually pivot in place properly now (with smooth animations and everything) and the camera preview stays properly oriented.

The problem is, the non-rotating view gets resized and everything gets misplaced when I rotate the device from portrait to landscape or vice-versa. How do I fix that?

4

1 回答 1

2

我得到了它的工作(尽管它花费了我应该花费的更多时间)。我需要设置非旋转视图的宽度和高度参数以在构建时删除,然后将以下内容添加到 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() 实现相同类型的接口(请参阅我的问题here)。我相信这种方法是创建此类接口的一种更简洁的方法,但我还不能让它在运行时不崩溃的情况下工作。

于 2015-10-27T20:07:42.630 回答