在应用扩展中检测方向的最佳方法是什么?

12

如何在应用程序扩展中检测设备的方向是最佳方法?我在这里找到的解决方案效果不一:

如何在iOS 8自定义键盘扩展中检测方向更改?

获取设备当前方向(应用程序扩展)

我查看了尺寸类和UITraitCollection,发现当设备实际处于横向时,设备错误地报告为纵向(不确定这是否是操作系统的错误,或者我没有正确地查询API)。

完成以下任务的最佳方法是什么:

  • 加载扩展时设备的当前方向
  • 设备将旋转到的方向
  • 设备已旋转到的方向

谢谢!

3个回答

20

我也遇到了这个问题,浏览了你的示例,但没有找到好的解决方案。 我的解决方法是:创建一个类,对 UIScreen 的一些值进行计算,并返回自定义的设备方向。

类头文件:

typedef NS_ENUM(NSInteger, InterfaceOrientationType) {
    InterfaceOrientationTypePortrait,
    InterfaceOrientationTypeLandscape
};

@interface InterfaceOrientation : NSObject

+ (InterfaceOrientationType)orientation;

@end

实现:

@implementation InterfaceOrientation

+ (InterfaceOrientationType)orientation{

    CGFloat scale = [UIScreen mainScreen].scale;
    CGSize nativeSize = [UIScreen mainScreen].currentMode.size;
    CGSize sizeInPoints = [UIScreen mainScreen].bounds.size;

    InterfaceOrientationType result;

    if(scale * sizeInPoints.width == nativeSize.width){
        result = InterfaceOrientationTypePortrait;
    }else{
        result = InterfaceOrientationTypeLandscape;
    }

    return result;
}

@end

我将其放置在viewWillLayoutSubviews或viewDidLayoutSubviews方法中,以捕获方向更改事件。

if([InterfaceOrientation orientation] == InterfaceOrientationTypePortrait){
     // portrait   
}else{
     // landscape   
}

如果你想获取设备方向的精确侧面(左、右、倒立),这种方法无法解决你的问题。它只能返回纵向或横向方向。

希望这可以帮到你。


我运行了那段代码,但它在设备实际为竖屏时返回了横屏视图。关于iOS 8方向改变,我仍感到困惑。据我所知,框架不会改变,而bounds会随着方向改变。现在它只是相反的吗? - user519274
user519274 - 感谢您的评论。它仍然有效。您是否将代码放在了正确的位置?它应该放在UIViewController的viewWillLayoutSubviews或viewDidLayoutSubviews方法中。 - Alexander Polovinka
但是如何获取设备方向是横屏左侧还是横屏右侧,就像这个问题所示:https://dev59.com/Rl8e5IYBdhLWcg3wssLG - Anand Suthar
Anand K,我在我的答案中进行了描述。提供的代码无法计算出横向或纵向模式的确切边缘。 - Alexander Polovinka

1

您可以通过在UIApplicationWillChangeStatusBarOrientationNotification上添加观察者,然后按以下方式提取方向,在扩展中获取设备方向。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
}

- (void)orientationWillChange:(NSNotification*)n
{
    UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[n.userInfo objectForKey:UIApplicationStatusBarOrientationUserInfoKey] intValue];

    if (orientation == UIInterfaceOrientationLandscapeLeft)
        //handle accordingly
    else if (orientation == UIInterfaceOrientationLandscapeRight)
        //handle accordingly
    else if (orientation == UIInterfaceOrientationPortraitUpsideDown)
        //handle accordingly
    else if (orientation == UIInterfaceOrientationPortrait)
        //handle accordingly
}

谢谢


0

我的共享扩展目标是 iOS 14.0 或更高版本,另一个用户提供的答案建议订阅 UIApplicationWillChangeStatusBarOrientationNotification 通知,但该通知在 iOS 13 中已被弃用。

UIApplication.h 中的弃用说明建议改用 viewWillTransitionToSize:withTransitionCoordinator:,这对我来说很有效。我已经在我的共享扩展根视图控制器上定义了此消息。我必须从提供的大小中推断方向,如下所示:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    if (size.height > size.width) {
        // setup your UI for portrait orientation
    }
    else {
        // setup your UI for landscape orientation
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接