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() を介して同じタイプのインターフェイスを実現するために、新しい制約構文のみを使用して (変換を使用せずに) いじくり回しました (それに関する私の質問はこちらを参照してください)。このアプローチは、このタイプのインターフェースを作成するためのよりクリーンな方法だと思いますが、実行時にクラッシュせずに機能させることはまだできていません。

于 2015-10-27T20:07:42.630 に答える