许多人讨论了模仿原生iOS相机应用程序的技术(其中UI元素在设备旋转时旋转)。我之前在这里提出了一个问题。大多数人建议锁定UI的方向,然后强制只对要旋转的元素进行变换。这种方法虽然可行,但元素不会像原生iOS应用程序中看到的那样平滑地旋转,而且会引起一些问题。具体来说,我的某些界面允许用户在不离开此界面的情况下分享,但是当共享视图旋转时,它会偏移中心。因此,我想找到一种不同的方式来解决这个问题。
我发现了一个链接到Apple's AVCam示例 ,这让我有了一个起点。虽然我对这些内容比较陌生,但我已经成功地将其从Obj-C转换为Swift。下面是我目前正在使用的关键元素:
我发现了一个链接到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)
}
我为相同转换方向的图标拥有单独的视图控制器。这些图标现在可以正确地在原地旋转(带有流畅的动画效果),相机预览也能保持正确的定位。
问题是,当我将设备从纵向模式旋转到横向模式或者反之时,不旋转的视图会被重新调整大小,所有的元素都会错位。我该如何解决这个问题?
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() nonRotatingView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)) }
- Grigory