iPhone/iPad:如何以编程方式获取屏幕宽度?

85

嗨,我想知道是否有一种方法可以以编程方式获取宽度。

我正在寻找一个足够通用的解决方案,可以适应iPhone 3GS、iPhone 4和iPad。此外,对于iPad设备,宽度应基于横向或纵向模式而改变。

有人知道如何实现吗?我已经寻找了一段时间...谢谢!


您是在寻找屏幕宽度、可用应用空间(不包括系统栏)的宽度还是特定视图的宽度? - VdesmedT
嗯,我不太确定。我想我只是想要设备的宽度(例如iPad纵向宽度为768,横向宽度为1024),但self.view.bounds似乎已经满足了这个需求。请看下面我的评论。 - Shai UI
请参考这个更全面的答案,该答案考虑了设备的方向。 - Drew Stephens
@DrewStephens 请看下面的答案,它考虑了方向,并且只有3行代码:D。 - memmons
7个回答

212

请查看UIScreen

例如:

CGFloat width = [UIScreen mainScreen].bounds.size.width;

如果您不想包含状态栏,可以查看applicationFrame属性(不会影响宽度)。

更新:事实证明UIScreen(-bounds或-applicationFrame)不考虑当前界面方向。更正确的方法是询问您的UIView其边界-假设此UIView已由其视图控制器自动旋转。

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    CGFloat width = CGRectGetWidth(self.view.bounds);
}

如果视图不是由视图控制器自动旋转的,则需要检查界面方向以确定视图边界的哪一部分表示“宽度”和“高度”。请注意,frame属性将为您提供窗口坐标空间中视图的矩形,该坐标空间(默认情况下)不会考虑接口方向。


3
实际上,当iPad横向放置时,这种方法不起作用。也就是说,如果我的模拟器是横向运行的,则它仍然返回768(而不是1024)。你认为我应该加一个if语句来检查方向,还是有更好的方法来获取宽度? - Shai UI
看起来你是对的,我已经更新了我的答案并提供了更多的想法。 - Alan Rogers
我最终在我的方法中只使用了“CGFloat width = CGRectGetWidth(self.view.bounds);”(不需要didRotateFromInterfaceOrientation)...所以至少self.view.bounds考虑了方向。谢谢! - Shai UI
5
如果其他读者看到这篇较旧的帖子,我发现self.view.bounds只有在didRotateFromInterfaceOrientation方法中才能完全准确。如果视图初始方向与IB中指定的目标方向相同,则在viewDidLoad和viewWillAppear中也会很准确。如果视图显示的方向与目标方向不同,那么在didRotateFromInterfaceOrientation之前都会调用viewDidLoad(和viewWillAppear),此时view.bounds将是不正确的。 - rimsky
在iOS 6的情况下,当我们使用模态控制器时,didRotateFromInterfaceOrientation方法将不会被调用。 - RK-
如果您的应用程序仅设计为横向或纵向模式,则需要比较宽度和高度以确定正确的尺寸。我们无法再可靠地获取方向。例如,我有一个仅设计为纵向模式的应用程序,但如果在iPad上以横向模式打开,则宽度和高度会混淆。 - Bobby

12
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screen);
//Bonus height.
CGFloat height = CGRectGetHeight(screen);

10
不考虑方向。 - rimsky

6

这可以用三行代码完成:

// grab the window frame and adjust it for orientation
UIView *rootView = [[[UIApplication sharedApplication] keyWindow] 
                                   rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];

3
这个很接近了,但如果正在显示 UIAlertView,则它将成为关键窗口,并且其 rootViewController 属性将为 nil。 - matt bezark
@mattbezark 确实如此。不过我认为这是一个边缘情况。有一种获取根视图的替代方法——虽然不像这个方法那么干净,但我会发布这个替代方法以防万一有人感兴趣。 - memmons
@memmons,可能有点晚了,但我对你的替代方案很感兴趣 :) - alexgophermix

1
使用:
NSLog(@"%f",[[UIScreen mainScreen] bounds].size.width) ;

0

iOS 9.0及以上版本目前无法可靠地获取方向。以下是我为一款仅支持竖屏模式设计的应用所使用的代码,因此,即使在横屏模式下打开应用程序,它仍将保持准确:

screenHeight = [[UIScreen mainScreen] bounds].size.height;
screenWidth = [[UIScreen mainScreen] bounds].size.width;
if (screenWidth > screenHeight) {
    float tempHeight = screenWidth;
    screenWidth = screenHeight;
    screenHeight = tempHeight;
}

0

使用这段代码会有帮助

[[UIScreen mainScreen] bounds].size.height
[[UIScreen mainScreen] bounds].size.width

-2

这里是一个获取屏幕尺寸的 Swift 方法,同时考虑了当前的界面方向:

var screenWidth: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.width
    } else {
        return UIScreen.mainScreen().bounds.size.height
    }
}
var screenHeight: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.height
    } else {
        return UIScreen.mainScreen().bounds.size.width
    }
}
var screenOrientation: UIInterfaceOrientation {
    return UIApplication.sharedApplication().statusBarOrientation
}

这些被包含在标准函数中:

https://github.com/goktugyil/EZSwiftExtensions


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