【问题标题】:How to get the screen width and height in iOS?如何在 iOS 中获取屏幕宽度和高度?
【发布时间】:2011-08-06 08:52:39
【问题描述】:

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

目前,我使用:

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

viewWillAppear:willAnimateRotationToInterfaceOrientation:duration:

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

【问题讨论】:

标签: cocoa-touch ios uikit screen


【解决方案1】:

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

您发布的代码的问题在于您指望视图大小与屏幕大小相匹配,但正如您所见,情况并非总是如此。如果你需要屏幕尺寸,你应该看看代表屏幕本身的对象,像这样:

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

拆分视图更新:在 cmets 中,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

【讨论】:

  • 方向实际上是在视图控制器级别管理的。看看Managing a View Controller's Interface Orientation。所以是的,看看你的视图控制器的 interfaceOrientation 属性。顺便说一句,您询问了屏幕大小,这就是我向您展示的内容,但要显示您的内容,您可能应该使用窗口的边界或屏幕的 applicationFrame,具体取决于您在做什么。
  • 请注意,这将返回 full 屏幕宽度而没有填充。只需从这些结果中减去您应用的填充(通常每边 20 个)即可获得大多数元素的“可用”空间
  • @NickDaugherty 是的,这就是重点——OP 想要屏幕尺寸。您在屏幕上放置对象的位置完全取决于您,并且取决于您正在构建的应用程序类型。例如,如果您正在显示照片或游戏界面,您可能根本不需要任何填充。
  • 但是请注意,这会返回一个以点为单位的值。因此,如果您期望以像素为单位的屏幕分辨率,则结果将不正确,您应该将结果乘以 [UIScreen scale]
  • 有人指出,既然a CGRect can have negative width or height,我们应该使用CGRectGetWidth()CGRectGetHeight(),而不是直接访问矩形中的size字段。我不认为这可能是屏幕矩形的问题,但我想这是需要注意的事情。
【解决方案2】:

小心,[UIScreen mainScreen] 也包含状态栏,如果您想检索应用程序的框架(不包括状态栏),您应该使用

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

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

【讨论】:

  • 在 ios 9.0 中已弃用
  • 由于 applicationFrame 已被弃用,替换为return [[UIScreen mainScreen] bounds].size.width;
【解决方案3】:

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

Main Answer

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

##Simple Function Answer

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

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

##Device Orientation Answer

let screenHeight: CGFloat
let statusBarOrientation = UIApplication.shared.statusBarOrientation
// it is important to do this after presentModalViewController:animated:
if (statusBarOrientation != .portrait
    && statusBarOrientation != .portraitUpsideDown) {
    screenHeight = UIScreen.main.bounds.size.width
} else {
    screenHeight = UIScreen.main.bounds.size.height
}

##Log Answer

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

【讨论】:

  • 日志答案中似乎有错字:应该是 UIScreen.mainScreen().bounds.size.width 吗?我得到一个没有“.bounds”的编译错误。
  • @skypecakes 我已经修复了包含“.bounds”的答案。感谢您的反馈。
  • applicationFrame 在 iOS 9 及更高版本中已弃用,替换为 return UIScreen.mainScreen().bounds].size.width
【解决方案4】:

我以前用过这些方便的方法:

- (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 似乎有未定义的来源。
  • 你得到 0,0 作为默认值吗?当我记录 fullScreenRect 时,它给了我:{{8.03294e-35, 3.09816e-40}, {480, 320}}。我选择用 CGRect temp = CGRectZero; 进行初始化;
  • UIInterfaceOrientationIsLandscape 不处理可能从 UIDevice 返回的“UIDeviceOrientationFaceUp”和“UIDeviceOrientationFaceDown”。
  • 你可能喜欢使用属性 screen.applicationFrame 而不是 screen.bounds 来处理状态栏。
  • 在某些情况下,applicationFrame 不会返回带有正确减去状态栏的框架(来自 splitview 的全屏模式)
【解决方案5】:

我意识到这是一篇旧帖子,但有时我发现#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 的答案,因为这似乎是最好的答案。
【解决方案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];

【讨论】:

  • 嗨,我在仅 iPad 横向应用程序上的 viewDidLoad 中使用它,是否有任何理由为什么它第一次获得正确的值,然后在每次加载之后值“翻转”,即它读取它作为横向第一视图,然后我导航离开并返回视图,即使没有进行方向更改,它似乎也将其读取为纵向?谢谢
  • @LukeMcneice 在我的生产代码中,我有一个断言来确保找到一个框架......我还没有让那个断言失败。 rootView 和 originalFrame 返回什么?
  • 我在单例中使用这种技术来获得方向校正的宽度/高度。但是,如果此代码在显示 convertRect 的 UIAlert 窗口返回大小(至少宽度)为 0 的adjustedFrame 时运行。有什么想法吗?
  • 啊。 UIAlertView 将自己插入为 keyWindow 的 rootViewController 视图。我有避免极端情况的逻辑,因为如果警报视图启动,则用户无法与键盘交互,因此当时通常不需要抓取键盘框架。
  • 感谢您的洞察力。我在横幅广告单例中使用了您的技术。这是告诉广告 api 新广告的屏幕框架大小的一种简单而好方法。由于我无法将横幅广告和 UIAlert 相互排除,因此我可能会退回到检测横向与纵向以及必要时强力切换 x/y。
【解决方案7】:

我们也要考虑设备的方向:

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;
}

【讨论】:

  • 很好的解决方案我这样做是为了让我的 iPad 应用程序在呈现模态 VC 时从嵌入式视图控制器内部以横向方式工作。
【解决方案8】:
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);

【讨论】:

    【解决方案9】:

    利用这些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)
        static let iOS13              = (iOSVersion.SYS_VERSION_FLOAT >= 13.0 && iOSVersion.SYS_VERSION_FLOAT < 14.0)
        static let iOS14              = (iOSVersion.SYS_VERSION_FLOAT >= 14.0 && iOSVersion.SYS_VERSION_FLOAT < 15.0)
        static let iOS15              = (iOSVersion.SYS_VERSION_FLOAT >= 15.0 && iOSVersion.SYS_VERSION_FLOAT < 16.0)
        
    }
    

    【讨论】:

      【解决方案10】:

      这里我更新了 swift 3

      applicationFrame已从 iOS 9 中弃用

      在swift 3中他们删除了()并且他们改变了一些命名约定,你可以参考这里Link

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

      【讨论】:

        【解决方案11】:

        现代答案:

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

        使用应用主窗口的大小:

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

        注意:上述方法在启动时可能会在窗口成为关键窗口之前得到错误的值。如果你只需要宽度,下面的方法非常推荐

        UIApplication.shared.statusBarFrame.width
        

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

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

        【讨论】:

          【解决方案12】:

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

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

          [UIScreen mainScreen].nativeBounds 物理屏幕的边界矩形,以像素为单位。此矩形基于纵向向上的设备。该值不会随着设备的旋转而改变。

          【讨论】:

            【解决方案13】:

            这是获取屏幕尺寸的 Swift 方法:

            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

            【讨论】:

              【解决方案14】:

              iOS 13+ 答案 (source of the code finding the key window):

              guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else {
                  return
              }
              
              let windowWidth = window.frame.width
              let windowHeight = window.frame.height
              

              【讨论】:

                【解决方案15】:

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

                【讨论】:

                  【解决方案16】:

                  斯威夫特 3.0

                  宽度

                  UIScreen.main.bounds.size.width
                  

                  身高

                  UIScreen.main.bounds.size.height
                  

                  【讨论】:

                    【解决方案17】:

                    对于 iPad 拆分窗口,[[UIScreen mainScreen] bounds] 不起作用,请改用[UIApplication sharedApplication].delegate.window.bounds

                    【讨论】:

                      【解决方案18】:

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

                      #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;
                      

                      【讨论】:

                      • 你能按照markdown格式缩进你的代码吗?目前,社区用户在审核队列中将其标记为“低质量”。
                      猜你喜欢
                      • 2011-09-25
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-06-12
                      • 1970-01-01
                      • 2012-12-17
                      • 2021-02-07
                      • 2010-11-25
                      相关资源
                      最近更新 更多