ChatGPT解决这个技术问题 Extra ChatGPT

How to get the screen width and height in iOS?

How can one get the dimensions of the screen in iOS?

Currently, I use:

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

in viewWillAppear: and willAnimateRotationToInterfaceOrientation:duration:

The first time I get the entire screen size. The second time i get the screen minus the nav bar.

Ensure that your app is actually full screen and you are not seeing black bars around it -- this may be your solution if you are

D
Daniel Springer

How can one get the dimensions of the screen in iOS?

The problem with the code that you posted is that you're counting on the view size to match that of the screen, and as you've seen that's not always the case. If you need the screen size, you should look at the object that represents the screen itself, like this:

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

Update for split view: In comments, Dmitry asked:

How can I get the size of the screen in the split view?

The code given above reports the size of the screen, even in split screen mode. When you use split screen mode, your app's window changes. If the code above doesn't give you the information you expect, then like the OP, you're looking at the wrong object. In this case, though, you should look at the window instead of the screen, like this:

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

Swift 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

Orientation is really managed at the view controller level. Take a look at Managing a View Controller's Interface Orientation. So yes, look at your view controller's interfaceOrientation property. BTW, you asked about the screen size, so that's what I showed you, but for displaying your content you should probably use the window's bounds or the screen's applicationFrame, depending on what you're doing.
it's useful to note that this returns the full screen width without padding. Simply subtract your app's padding (usually 20 on each side) from these results to get the 'usable' space for most elements
@NickDaugherty Yes, that's the point -- the OP wanted the screen dimensions. Where you put objects on the screen is entirely up to you and depends on what type of app you're building. If you're displaying a photo or a game interface, for example, you might not want any padding at all.
Note however that this returns a value measured in points. So if you were expecting the screen resolution in pixels, the result would be incorrect, and you should multiply the result by [UIScreen scale].
Someone pointed out that since a CGRect can have negative width or height, we should use CGRectGetWidth() and CGRectGetHeight() instead of directly accessing the size field in the rectangle. I don't think it's ever likely to be a problem with respect to the screen rectangle, but I suppose it's something to be aware of.
E
Ege Akpinar

Careful, [UIScreen mainScreen] contains status bar as well, if you want to retrieve the frame for your application (excluding status bar) you should use

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

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

deprecated in ios 9.0
since applicationFrame is deprecated, replace with return [[UIScreen mainScreen] bounds].size.width;
M
Michal Šrůtek

I've translated some of the above Objective-C answers into Swift code. Each translation is proceeded with a reference to the original answer.

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)")

Seems like there's a typo in the Log Answer: Should it be UIScreen.mainScreen().bounds.size.width? I get a compile error without the ".bounds".
@skypecakes I've fixed the answer to include ".bounds". Thanks for the feedback.
applicationFrame is deprecated in iOS 9 and above, replace with return UIScreen.mainScreen().bounds].size.width
1
16 revs, 2 users 94%

I have used these convenience methods before:

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

Nice solution, but be careful that temp seems to have undefined origin.
Do you get 0,0 as default? When I logged the fullScreenRect, it gave me: {{8.03294e-35, 3.09816e-40}, {480, 320}}. I chose to initialized with CGRect temp = CGRectZero;
UIInterfaceOrientationIsLandscape does not handle 'UIDeviceOrientationFaceUp' and 'UIDeviceOrientationFaceDown' which may be returned from UIDevice.
You may like to use the property screen.applicationFrame instead of screen.bounds which takes care of the status bar.
Turns out in some cases applicationFrame dosn't return frame with a correctly subtracted status bar (full screen modals from a splitview)
A
A Random User

I realize that this is an old post, but sometimes I find it useful to #define constants like these so I do not have to worry about it:

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

The above constant should return the correct size no matter the device orientation. Then getting the dimensions is as simple as:

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

You might want to base the macro on AnswerBot's answer since that seems like the best answer.
m
memmons

It's very, very easy to get your device size as well as take into account the orientation:

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

Hi, I use this in viewDidLoad on an iPad landscape only app, is there any reason why it gets the correct value first time, then the value 'flips' on every load after than, ie it reads it as lanscape first view, then I navigate away and back to the view and it seems to read it as portrait even tho no orientation change was made? Thanks
@LukeMcneice In my production code I have an assert to make sure that a frame is found...I have yet to have that assert fail. What is being returned for rootView and originalFrame?
I am using this technique in a singleton to get the orientation-corrected width/height. However, if this code runs while a UIAlert window showing the convertRect returns adjustedFrame with a size (width at least) of 0. Any thoughts what is going on with that?
Ah. An UIAlertView will insert itself as the keyWindow's rootViewController view. I have logic that avoids the corner case because if an alert view is up, the user can't interact with the keyboard, so there is typically no need to grab the keyboard frame at that time.
Thanks for the insight. I was using your technique in a banner ad singleton. It was a simple and nice way of telling the ad api the size of the screen frame for a new ad. Since I will not be able to mutually exclude banner ads and UIAlert's I will likely fall back to detecting landscape vs. portrait and brute force switching x/y as necessary.
O
Oleh Kudinov

We have to consider the orientation of device too:

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

Good solution I did this to get my iPad app working in landscape from inside an embedded view controller when presenting a modal VC.
G
Gaurav Gilani
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);

b
badhanganesh

Make use of these Structs to know useful info about the current device in 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)
    
}

k
karthikeyan

Here i have updated for swift 3

applicationFrame deprecated from iOS 9

In swift three they have removed () and they have changed few naming convention, you can refer here Link

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

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

l
leavez

The modern answer:

if your app support split view on iPad, this problem becomes a little complicated. You need window's size, not the screen's, which may contain 2 apps. Window's size may also vary while running.

Use app's main window's size:

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

Note: The method above may get wrong value before window becoming key window when starting up. if you only need width, method below is very recommended:

UIApplication.shared.statusBarFrame.width

The old solution using UIScreen.main.bounds will return the device's bounds. If your app running in split view mode, it get the wrong dimensions.

self.view.window in the hottest answer may get wrong size when app contains 2 or more windows and the window have small size.


J
John Erck

If you want screen width/height regardless of device orientation (good for sizing portrait only view controllers being launched from landscape orientations):

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

[UIScreen mainScreen].nativeBounds <-- From the docs --> The bounding rectangle of the physical screen, measured in pixels. This rectangle is based on the device in a portrait-up orientation. This value does not change as the device rotates.


E
Esqarrouth

Here is a Swift way to get screen sizes:

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
}

These are included as a standard function in:

https://github.com/goktugyil/EZSwiftExtensions


T
Tamás Sengel

iOS 13+ answer (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

H
Himanshu jamnani

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


A
Amul4608

swift 3.0

for width

UIScreen.main.bounds.size.width

for height

UIScreen.main.bounds.size.height

y
yclod

For iPad split window, the [[UIScreen mainScreen] bounds] doesn't work, use [UIApplication sharedApplication].delegate.window.bounds instead.


m
m4n0

You can place these macros in your pch file and used at anywhere in project by using "SCREEN_WIDTH"

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

and "SCREEN_HEIGHT"

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

Example of using:

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

Can you please indent your code according to the markdown format? Currently this was flagged as "low quality" by community users in the review queue.