旋转设备时是不是可以对 UIView 使用自定义旋转?
Posted
技术标签:
【中文标题】旋转设备时是不是可以对 UIView 使用自定义旋转?【英文标题】:Is it possible to use custom rotation for UIView when rotating device?旋转设备时是否可以对 UIView 使用自定义旋转? 【发布时间】:2014-12-09 02:27:20 【问题描述】:我正在为我的应用程序创建一个 camera-viewController,并且我想使用与 ios 默认相机应用程序中使用的相同的想法:记录按钮始终位于设备的同一侧。内容只是随自己的轴旋转,而不是整个屏幕翻转。
我已经“成功”创建了这个。我只允许风景。打开后是这样的:
Figure 1
<- top of device
------------------------------
| ------------------- |
|| | |
|| | --- |
|| camera-view | | ^ | |
|| | --- |
|| | |
| ------------------- |
-----------------------------
当将视图旋转到另一侧时,每个元素都会围绕自己旋转以显示这一点(相机除外):
Figure 2
top of device ->
------------------------------
| ------------------- |
| | ||
| --- | ||
| | ^ | | camera-view || [top of device ->]
| --- | ||
| | ||
| ------------------- |
-----------------------------
这样做的问题是整个视图会旋转,因此屏幕总是会显示Figure 1
,而“设备顶部”会改变方向。
通过在-(BOOL)shouldAutorotate
中返回NO
,我得到了我想要的结果,尽管一切都会自然而然地颠倒过来。
然后,通过注册 device-orientation-norifications 并使用我自己的选择器,我可以使用例如 [btnRecord setTransform:CGAffineTransformMakeRotation(-M_PI)];
在旋转时为每个控件设置变换,同时防止控制器实际旋转,我得到了我想要的结果。有点。
问题:
当使用我上面描述的方法时,我在视觉上得到了正确的结果,但我怀疑我应该用另一种方式来管理它。当我收到来自其他应用程序(例如 Mail、Facebook 等)的通知时,它们将始终以原始方向显示。这是有道理的。如果这个 viewController 从 LandscapeLeft 开始,然后转到 LandscapeRight,我的所有控件和整个视图都会动画并且看起来非常适合该方向,但是传入的通知将在屏幕底部显示颠倒。这当然是我在shouldAutorotate
中返回NO
的结果。
在默认的Camera-app中,他们已经解决了,所以它一定是可能的。 有没有办法启用自动旋转,但同时防止控制器的视图实际旋转?当时我能想到的唯一解决方案是创建一个动画,它可以完美地抵消旋转动画,保持它在海湾,但这听起来很糟糕,我想找到一个更好的方法。
【问题讨论】:
隐藏状态栏吗? 【参考方案1】:您可以使用加速度计检测您的应用被激活的方向:
- (void)applicationWillEnterForeground:(UIApplication*)application
// [motionManager stopAccelerometerUpdates] doesn't stop
// all gathered accelerometer data, but we want trigger it once.
static BOOL read = NO;
// applicationWillEnterForeground will happen lot of times :-)
read = NO;
CMMotionManager* motionManager = [[CMMotionManager alloc]init];
[motionManager
startAccelerometerUpdatesToQueue:
[[NSOperationQueue alloc] init]
withHandler:
^(CMAccelerometerData* data, NSError* error)
if (!read)
read = YES;
[motionManager stopAccelerometerUpdates];
CGFloat accx = data.acceleration.x;
CGFloat accy = data.acceleration.y;
dispatch_async(
dispatch_get_main_queue(),
^
[[UIApplication sharedApplication]
setStatusBarOrientation:
deviceOrientationFromAcceleration(accx, accy)
animated:NO];
);
];
deviceOrientationFromAcceleration()
函数定义为
int deviceOrientationFromAcceleration(CGFloat x, CGFloat y)
// Get the current device angle
float xx = -x;
float yy = y;
float angle = atan2(yy, xx);
if (angle >= -2.25f && angle <= -0.75f)
return UIInterfaceOrientationPortrait;
else if (angle >= -0.75f && angle <= 0.75f)
return UIInterfaceOrientationLandscapeRight;
else if (angle >= 0.75f && angle <= 2.25f)
return UIInterfaceOrientationPortraitUpsideDown;
else if (angle <= -2.25f || angle >= 2.25f)
return UIInterfaceOrientationLandscapeLeft;
return 0;
【讨论】:
以上是关于旋转设备时是不是可以对 UIView 使用自定义旋转?的主要内容,如果未能解决你的问题,请参考以下文章