我正在制作一款壁纸应用程序,并希望检查用户是否在其iOS 7设备上启用了视差效果。在objective-C中,有没有一种方法可以检查这个布尔值?苹果公司授权我们开发人员访问此功能吗?
例如,如果启用了视差效果,请执行步骤1,否则执行步骤2。
我正在制作一款壁纸应用程序,并希望检查用户是否在其iOS 7设备上启用了视差效果。在objective-C中,有没有一种方法可以检查这个布尔值?苹果公司授权我们开发人员访问此功能吗?
例如,如果启用了视差效果,请执行步骤1,否则执行步骤2。
截至iOS 8:
// Returns whether the system preference for reduce motion is enabled
UIKIT_EXTERN BOOL UIAccessibilityIsReduceMotionEnabled() NS_AVAILABLE_IOS(8_0);
UIKIT_EXTERN NSString *const UIAccessibilityReduceMotionStatusDidChangeNotification NS_AVAILABLE_IOS(8_0);
对于 iOS 8 及之前的版本,我认为没有一种合法的方法可以确定。
UIInterpolatingMotionEffect
的特性,如果运动是默认的,则会执行某些操作,但如果减少运动,则不执行任何操作。UIView
类,并在应用程序启动时立即附加一个UIInterpolatingMotionEffect
实例。如果更改了属性,则设置标志。稍后检查该标志。编辑:示例代码。在评论中讨论的问题是该属性必须是可动画的,这导致需要手动轮询。在您的应用程序中的某个位置添加此视图的实例,最好是在启动时,并使其保持在整个应用程序的生命周期内保持在屏幕上,当然前提是您的视图控制器层次结构允许它。然后观察parallaxHasOccurred属性。它符合KVO,或者您可以进行轮询。正如讨论的那样,它可能会生成错误的负面结果,但永远不会生成错误的正面结果。
@interface PTParallaxTestView : UIView
// this key is KVO compliant
@property (nonatomic, assign) BOOL parallaxHasOccurred;
@end
@implementation PTParallaxTestView
{
CGPoint _basePosition;
UIMotionEffectGroup *_effectGroup;
}
- (void)didMoveToSuperview
{
// cancel any detection loop we may have ongoing
[NSObject cancelPreviousPerformRequestsWithTarget:self];
// if anything still in doubt and we're on a view then start the
// detection loop
if(!self.parallaxHasOccurred && self.superview)
{
// add motion effects if they're not already attached; attach both to the centre property
if(!_effectGroup)
{
UIInterpolatingMotionEffect *horizontalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
horizontalMotionEffect.minimumRelativeValue = @(0);
horizontalMotionEffect.maximumRelativeValue = @(100);
UIInterpolatingMotionEffect *verticalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
verticalMotionEffect.minimumRelativeValue = @(0);
verticalMotionEffect.maximumRelativeValue = @(100);
_effectGroup = [[UIMotionEffectGroup alloc] init];
_effectGroup.motionEffects = @[verticalMotionEffect, horizontalMotionEffect];
[self addMotionEffect:_effectGroup];
}
// kick off inspection in 0.1 seconds; we'll subsequently inspect
// every 0.5 seconds
[self performSelector:@selector(beginCheckingPresentationPosition) withObject:nil afterDelay:0.1];
}
}
- (void)beginCheckingPresentationPosition
{
// set the base position and do the first check in 0.5 seconds
_basePosition = [[[self layer] presentationLayer] position];
[self performSelector:@selector(checkPresentationPosition) withObject:nil afterDelay:0.5];
}
- (void)checkPresentationPosition
{
// quick note on presentationLayer:
//
// The property supplied to UIInterpolatingMotionEffect must be animatable. So we can't just create our own.
// UIKit will then apply effects directly to the layer. Furthermore, the layer itself will act as if in a
// perpetual animation so its properties won't directly be affected. We'll have to query the presentationLayer.
// (and that's also why we're pulling rather than using KVO or a suitable subclass to push)
//
CGPoint newPosition = [[[self layer] presentationLayer] position];
// if the position has changed since the original test then things are in motion
if(fabs(newPosition.x - _basePosition.x) > 0.125 || fabs(newPosition.y - _basePosition.y) > 0.125)
self.parallaxHasOccurred = YES;
// check again in 0.5 seconds only if we don't already know the answer
if(!self.parallaxHasOccurred)
[self performSelector:@selector(checkPresentationPosition) withObject:nil afterDelay:0.5];
}
@end
UIInterpolatingMotionEffect
技巧的发现很不错。+1 - Gabriele Petronella对于不支持视差效果的设备(例如 iPhone 5 之前的任何 iPhone 型号),您只需检查型号,并确保没有开启视差效果。
对于支持它的设备,您应该以编程方式检查减少动作辅助功能设置,但显然没有公共 API 可以检查该选项是否开启。
根据UIKit 函数参考,您可以执行的唯一检查如下所示
UIAccessibilityPostNotification
:发布无障碍通知。UIAccessibilityIsVoiceOverRunning
:检查屏幕阅读器是否正在运行。UIAccessibilityIsClosedCaptioningEnabled
:检查字幕是否启用。UIAccessibilityRequestGuidedAccessSession
:请求引导访问会话。UIAccessibilityIsGuidedAccessEnabled
:检查引导访问是否启用。UIAccessibilityIsInvertColorsEnabled
:检查反转颜色是否启用。UIAccessibilityIsMonoAudioEnabled
:检查单声道音频是否启用。UIAccessibilityZoomFocusChanged
:缩放焦点发生变化。UIAccessibilityRegisterGestureConflictWithZoom
:将手势冲突注册到缩放中。UIAccessibilityConvertFrameToScreenCoordinates
:将框架转换为屏幕坐标系。UIAccessibilityConvertPathToScreenCoordinates
:将路径转换为屏幕坐标系。