如何在iOS中获取屏幕的宽度和高度?


506

如何在iOS中获取屏幕尺寸?

目前,我使用:

lCurrentWidth = self.view.frame.size.width;
lCurrentHeight = self.view.frame.size.height;

viewWillAppear:willAnimateRotationToInterfaceOrientation:duration:

第一次获得整个屏幕尺寸。第二次我得到的屏幕减去导航栏。

Answers:


1063

如何在iOS中获取屏幕尺寸?

您发布的代码的问题在于您要依靠视图的大小来匹配屏幕的大小,而且正如您所看到的,情况并非总是如此。如果需要屏幕尺寸,则应查看代表屏幕本身的对象,如下所示:

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

拆分视图的更新:在评论中,Dmitry问:

如何在拆分视图中获取屏幕尺寸?

上面给出的代码即使在分屏模式下也报告屏幕的大小。使用分屏模式时,应用程序的窗口会更改。如果上面的代码没有给您期望的信息,那么像OP一样,您正在寻找错误的对象。但是,在这种情况下,您应该查看窗口而不是屏幕,如下所示:

CGRect windowRect = self.view.window.frame;
CGFloat windowWidth = windowRect.size.width;
CGFloat windowHeight = windowRect.size.height;

斯威夫特4.2

let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width
let screenHeight = screenRect.size.height

// split screen            
let windowRect = self.view.window?.frame
let windowWidth = windowRect?.size.width
let windowHeight = windowRect?.size.height

7
方向实际上是在视图控制器级别上进行管理的。看一下管理View Controller的界面方向。是的,请查看您的视图控制器的interfaceOrientation属性。顺便说一句,您询问了屏幕大小,所以这就是我给您显示的内容,但是对于显示内容,您可能应该使用窗口的边界或屏幕的applicationFrame,具体取决于您正在执行的操作。
Caleb

2
请注意,这会返回整个屏幕宽度而不会填充,这很有用。只要从这些结果减去你的应用程序的填充(通常每侧20),以获得“可用”空间对于大多数的元素
尼克·多赫蒂

2
@NickDaugherty是的,这就是关键-OP需要屏幕尺寸。在屏幕上放置对象的位置完全取决于您,并且取决于您要构建的应用程序类型。例如,如果要显示照片或游戏界面,则可能根本不需要任何填充。
Caleb

3
但是请注意,这将返回以磅为单位的值。因此,如果您期望以像素为单位的屏幕分辨率,则结果将是不正确的,并且应将结果乘以[UIScreen scale]
Robotbugs

3
有人指出,由于CGRect的宽度或高度可以为负,因此我们应该使用CGRectGetWidth()CGRectGetHeight()不是直接访问size矩形中的字段。对于屏幕矩形,我不认为这是个问题,但是我想这是需要注意的事情。
Caleb 2014年

64

小心[UIScreen mainScreen]也包含状态栏,如果要检索应用程序的框架(状态栏除外),则应使用

+ (CGFloat) window_height   {
    return [UIScreen mainScreen].applicationFrame.size.height;
}

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}

4
在ios 9.0中已弃用
Zakaria Darwish

6
由于applicationFrame已弃用,请替换为return [[UIScreen mainScreen] bounds].size.width;
lizzy81 '16

44

我已经将上述一些Objective-C答案翻译成了Swift代码。每次翻译都参考原始答案。

主要答案

let screen = UIScreen.main.bounds
let screenWidth = screen.size.width
let screenHeight = screen.size.height

简单功能答案

func windowHeight() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.width
}

设备方向答案

var screenHeight : CGFloat
let statusBarOrientation = UIApplication.sharedApplication().statusBarOrientation
// it is important to do this after presentModalViewController:animated:
if (statusBarOrientation != UIInterfaceOrientation.Portrait
    && statusBarOrientation != UIInterfaceOrientation.PortraitUpsideDown){
    screenHeight = UIScreen.mainScreen().applicationFrame.size.width
} else {
    screenHeight = UIScreen.mainScreen().applicationFrame.size.height
}

记录答案

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")

似乎在日志答案中有错字:应该是UIScreen.mainScreen()。bounds.size.width吗?我收到没有“ .bounds”的编译错误。

@skypecakes我已将答案固定为包含“ .bounds”。感谢您的反馈。
Martin Woolstenhulme,2015年

在iOS 9和更高版本中不建议使用applicationFrame,请替换为return UIScreen.mainScreen().bounds].size.width
Suhaib

39

我之前使用过以下便捷方法:

- (CGRect)getScreenFrameForCurrentOrientation {
    return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {

    CGRect fullScreenRect = [[UIScreen mainScreen] bounds];

    // implicitly in Portrait orientation.
    if (UIInterfaceOrientationIsLandscape(orientation)) {
      CGRect temp = CGRectZero;
      temp.size.width = fullScreenRect.size.height;
      temp.size.height = fullScreenRect.size.width;
      fullScreenRect = temp;
    }

    if (![[UIApplication sharedApplication] statusBarHidden]) {
      CGFloat statusBarHeight = 20; // Needs a better solution, FYI statusBarFrame reports wrong in some cases..
      fullScreenRect.size.height -= statusBarHeight;
    }

    return fullScreenRect;
} 

好的解决方案,但请注意,temp似乎具有不确定的来源。
szemian 2012年

4
您默认得到0,0吗?当我登录fullScreenRect时,它给了我:{{8.03294e-35,3.09816e-40},{480,320}}。我选择使用CGRect进行初始化temp = CGRectZero;
szemian

1
UIInterfaceOrientationIsLandscape不处理可能从UIDevice返回的'UIDeviceOrientationFaceUp'和'UIDeviceOrientationFaceDown'。
Andriy

6
您可能希望使用属性screen.applicationFrame而不是screen.bounds来处理状态栏。
Geraud.ch 2012年

在某些情况下,applicationFrame不会返回带有正确减去的状态栏的帧(来自splitview的全屏模式)
Luke Mcneice 2013年

15

我意识到这是一篇过时的文章,但是有时我发现#define这样的常量很有用,因此我不必担心:

#define DEVICE_SIZE [[[[UIApplication sharedApplication] keyWindow] rootViewController].view convertRect:[[UIScreen mainScreen] bounds] fromView:nil].size

无论设备方向如何,以上常量均应返回正确的大小。然后获取尺寸非常简单:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;

您可能希望将宏基于AnswerBot的答案,因为这似乎是最佳答案。
griotspeak

13

获取设备尺寸以及考虑方向非常非常容易:

// 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];

嗨,我在仅iPad横向应用程序的viewDidLoad中使用了此函数,是否有任何原因使其首次获得正确的值,然后在每次加载后值“翻转”,即它将其读取为lanscape第一视图,然后我导航并返回视图,即使没有进行任何方向更改,它似乎也以肖像形式阅读?谢谢
craigk

@LukeMcneice在我的生产代码中,我有一个断言来确保找到一个框架...我还没有断言失败。rootView和originalFrame返回什么?
记忆

我在单例中使用此技术来获取经过方向校正的宽度/高度。但是,如果这段代码在显示convertRect的UIAlert窗口返回时,返回的AdjustedFrame的大小(至少为宽度)为0。那有什么想法吗?
Electro-Bunny

啊。一个UIAlertView将自身插入作为keyWindow的RootViewController的看法。我有避免出现极端情况的逻辑,因为如果出现警报视图,则用户将无法与键盘进行交互,因此通常无需在那时抓住键盘框架。
回忆录

感谢您的见解。我在横幅广告单例中使用了您的技术。这是一种告诉广告api新广告的屏幕框架大小的简便方法。由于我将无法相互排除横幅广告和UIAlert的横幅广告,因此我可能会退回到检测横向与纵向以及根据需要进行蛮力切换x / y。
Electro-Bunny

9

我们也必须考虑设备的方向:

CGFloat screenHeight;
// it is important to do this after presentModalViewController:animated:
if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
    screenHeight = [UIScreen mainScreen].applicationFrame.size.height;
}
else{
    screenHeight = [UIScreen mainScreen].applicationFrame.size.width;
}

很好的解决方案我这样做是为了在演示模式VC时使我的iPad应用从嵌入式视图控制器内部横向运行。
StackRunner 2014年


5

在这里,我已经更新了迅速3

自iOS 9起不推荐使用applicationFrame

很快,他们删除了()并且更改了一些命名约定,您可以在这里参考链接

func windowHeight() -> CGFloat {
    return UIScreen.main.bounds.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.main.bounds.size.width
}

4

现代答案:

如果您的应用程序支持iPad上的拆分视图,则此问题会变得有些复杂。您需要窗口的大小,而不是屏幕的大小,它可能包含2个应用程序。运行时窗口的大小也可能会有所不同。

使用应用程序主窗口的大小:

UIApplication.shared.delegate?.window??.bounds.size ?? .zero

注意:以上方法在启动时可能会在窗口变为关键窗口之前得到错误的值。如果只需要宽度,则强烈建议使用以下方法:

UIApplication.shared.statusBarFrame.width

旧解决方案使用 UIScreen.main.bounds将返回设备的边界。如果您的应用程序以拆分视图模式运行,则其尺寸错误。

self.view.window 当应用包含2个或更多窗口且窗口尺寸较小时,最热的答案中的尺寸可能会错误。


4

利用这些Structs信息了解有关Swift 3.0中当前设备的有用信息

struct ScreenSize { // Answer to OP's question

    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)

}

struct DeviceType { //Use this to check what is the device kind you're working with

    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_SE         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_7          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_7PLUS      = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0

}


struct iOSVersion { //Get current device's iOS version

    static let SYS_VERSION_FLOAT  = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS7               = (iOSVersion.SYS_VERSION_FLOAT >= 7.0 && iOSVersion.SYS_VERSION_FLOAT < 8.0)
    static let iOS8               = (iOSVersion.SYS_VERSION_FLOAT >= 8.0 && iOSVersion.SYS_VERSION_FLOAT < 9.0)
    static let iOS9               = (iOSVersion.SYS_VERSION_FLOAT >= 9.0 && iOSVersion.SYS_VERSION_FLOAT < 10.0)
    static let iOS10              = (iOSVersion.SYS_VERSION_FLOAT >= 10.0 && iOSVersion.SYS_VERSION_FLOAT < 11.0)
    static let iOS11              = (iOSVersion.SYS_VERSION_FLOAT >= 11.0 && iOSVersion.SYS_VERSION_FLOAT < 12.0)
    static let iOS12              = (iOSVersion.SYS_VERSION_FLOAT >= 12.0 && iOSVersion.SYS_VERSION_FLOAT < 13.0)

}

3

如果您希望屏幕宽度/高度与设备方向无关(适合调整从纵向方向启动的仅纵向视图控制器的大小):

CGFloat screenWidthInPoints = [UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale;
CGFloat screenHeightInPoints = [UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale;

[UIScreen mainScreen] .nativeBounds <-来自文档->物理屏幕的边界矩形,以像素为单位。该矩形基于设备的纵向放置。该值不会随着设备旋转而改变。


2

这是一种获取屏幕尺寸的快捷方法:

print(screenWidth)
print(screenHeight)

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


1

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


1

迅捷3.0

宽度

UIScreen.main.bounds.size.width

身高

UIScreen.main.bounds.size.height

-2

您可以使用“ SCREEN_WIDTH”将这些宏放置在pch文件中,并在项目中的任何位置使用

#define SCREEN_WIDTH                ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)

和“ SCREEN_HEIGHT”

#define SCREEN_HEIGHT               ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation ==   UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)

使用示例:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;

您可以根据降价格式缩进代码吗?当前,社区用户在评论队列中将此标记为“低质量”。
Manoj Kumar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.