Làm cách nào để có được chiều rộng và chiều cao màn hình trong iOS?


506

Làm thế nào người ta có thể có được kích thước của màn hình trong iOS?

Hiện tại, tôi sử dụng:

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

trong viewWillAppear:willAnimateRotationToInterfaceOrientation:duration:

Lần đầu tiên tôi có được toàn bộ kích thước màn hình. Lần thứ hai tôi nhận được màn hình trừ thanh điều hướng.

Câu trả lời:


1063

Làm thế nào người ta có thể có được kích thước của màn hình trong iOS?

Vấn đề với mã mà bạn đã đăng là bạn đang tính kích thước khung nhìn để khớp với màn hình và như bạn đã thấy không phải lúc nào cũng như vậy. Nếu bạn cần kích thước màn hình, bạn nên nhìn vào đối tượng đại diện cho màn hình, như thế này:

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

Cập nhật cho chế độ xem chia nhỏ: Trong các bình luận, Dmitry đã hỏi:

Làm cách nào tôi có thể nhận được kích thước của màn hình trong chế độ xem chia?

Mã được đưa ra ở trên báo cáo kích thước của màn hình, ngay cả trong chế độ chia màn hình. Khi bạn sử dụng chế độ chia màn hình, cửa sổ ứng dụng của bạn sẽ thay đổi. Nếu đoạn mã trên không cung cấp cho bạn thông tin mà bạn mong đợi, thì giống như OP, bạn đang nhìn nhầm đối tượng. Tuy nhiên, trong trường hợp này, bạn nên nhìn vào cửa sổ thay vì màn hình, như thế này:

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

7
Định hướng được thực sự quản lý ở cấp độ điều khiển xem. Hãy xem Quản lý Định hướng Giao diện của Trình điều khiển Chế độ xem . Vì vậy, có, nhìn vào thuộc tính interfaceOrientation của trình điều khiển xem của bạn. BTW, bạn đã hỏi về kích thước màn hình, vì vậy đó là những gì tôi đã cho bạn xem, nhưng để hiển thị nội dung của bạn, có lẽ bạn nên sử dụng giới hạn của cửa sổ hoặc Khung ứng dụng của màn hình, tùy thuộc vào những gì bạn đang làm.
Caleb

2
thật hữu ích khi lưu ý rằng điều này trả về chiều rộng toàn màn hình mà không cần đệm. Chỉ cần trừ phần đệm của ứng dụng của bạn (thường là 20 ở mỗi bên) khỏi các kết quả này để có được không gian 'có thể sử dụng' cho hầu hết các yếu tố
Nick Daugherty

2
@NickDaugherty Vâng, đó là điểm chính - OP muốn kích thước màn hình. Nơi bạn đặt các đối tượng trên màn hình hoàn toàn tùy thuộc vào bạn và tùy thuộc vào loại ứng dụng bạn đang xây dựng. Ví dụ: nếu bạn đang hiển thị ảnh hoặc giao diện trò chơi, bạn có thể không muốn bất kỳ phần đệm nào cả.
Caleb

3
Tuy nhiên, lưu ý rằng điều này trả về một giá trị được đo bằng điểm. Vì vậy, nếu bạn đang mong đợi độ phân giải màn hình tính bằng pixel, kết quả sẽ không chính xác và bạn nên nhân kết quả với [UIScreen scale].
Robotbugs

3
Ai đó đã chỉ ra rằng vì CGRect có thể có chiều rộng hoặc chiều cao âm , chúng ta nên sử dụng CGRectGetWidth()CGRectGetHeight()thay vì truy cập trực tiếp vào sizetrường trong hình chữ nhật. Tôi không nghĩ nó có thể là một vấn đề liên quan đến hình chữ nhật trên màn hình, nhưng tôi cho rằng đó là điều cần phải biết.
Caleb

64

Cẩn thận, [UIScreen mainScreen] cũng chứa thanh trạng thái, nếu bạn muốn truy xuất khung cho ứng dụng của mình (không bao gồm thanh trạng thái), bạn nên sử dụng

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

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

4
không dùng nữa trong ios 9.0
Zakaria Darwish

6
kể từ khi applicationFrame không được chấp nhận, hãy thay thế bằngreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81

44

Tôi đã dịch một số câu trả lời Objective-C ở trên sang mã Swift. Mỗi bản dịch được tiến hành với một tham chiếu đến câu trả lời ban đầu.

Câu trả lời chính

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

Chức năng trả lời đơn giản

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

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

Định hướng thiết bị Trả lời

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
}

Đăng nhập trả lời

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

Có vẻ như có một lỗi đánh máy trong Nhật ký Trả lời: Có nên là UIScreen.mainScreen (). Bound.size. Thong? Tôi nhận được một lỗi biên dịch mà không có ".bound".
đá

@skypecakes Tôi đã sửa câu trả lời để bao gồm ".bound". Cảm ơn vì bạn đã phản hồi.
Martin Woolstenhulme

applicationFrame không được dùng trong iOS 9 trở lên, thay thế bằngreturn UIScreen.mainScreen().bounds].size.width
Suhaib

39

Tôi đã sử dụng các phương pháp thuận tiện này trước đây:

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

Giải pháp tốt đẹp, nhưng hãy cẩn thận rằng temp dường như có nguồn gốc không xác định.
szantic

4
Bạn có nhận được 0,0 như mặc định? Khi tôi đăng nhập fullScreenRect, nó đã cho tôi: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Tôi đã chọn khởi tạo với CGRect temp = CGRectZero;
szantic

1
UIInterfaceOrientationIsLandscape không xử lý 'UIDeviceOrientationFaceUp' và 'UIDeviceOrientationFaceDown' có thể được trả về từ UIDevice.
Andriy

6
Bạn có thể muốn sử dụng thuộc tính screen.applicationFrame thay vì screen.bound chăm sóc thanh trạng thái.
Geraud.ch

Hóa ra trong một số trường hợp, ứng dụng Khung không trả lại khung với thanh trạng thái được trừ chính xác (phương thức toàn màn hình từ một màn hình chia nhỏ)
Luke Mcneice

15

Tôi nhận ra rằng đây là một bài viết cũ, nhưng đôi khi tôi thấy nó hữu ích với các hằng số #define như thế này vì vậy tôi không phải lo lắng về nó:

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

Hằng số trên sẽ trả về kích thước chính xác cho dù định hướng thiết bị. Sau đó, nhận được kích thước đơn giản như:

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

Bạn có thể muốn dựa trên macro của câu trả lời của answerBot vì đó có vẻ là câu trả lời hay nhất.
Griotspeak

13

Rất dễ dàng để có được kích thước thiết bị của bạn cũng như tính đến định hướng:

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

Xin chào, tôi sử dụng điều này trong viewDidLoad trên ứng dụng chỉ dành cho iPad, có lý do nào khiến nó nhận được giá trị chính xác ngay lần đầu tiên không, sau đó giá trị 'lật' trên mỗi lần tải sau đó, tức là nó đọc nó dưới dạng xem lanscape trước, sau đó tôi điều hướng đi và quay lại chế độ xem và dường như đọc nó dưới dạng chân dung ngay cả khi không có thay đổi định hướng nào được thực hiện? Cảm ơn
craigk

@LukeMcneice Trong mã sản xuất của tôi, tôi có một xác nhận để đảm bảo rằng một khung được tìm thấy ... Tôi vẫn chưa có xác nhận đó thất bại. Điều gì đang được trả về cho rootView và originalFrame?
memmons

Tôi đang sử dụng kỹ thuật này trong một đĩa đơn để có được chiều rộng / chiều cao được điều chỉnh theo hướng. Tuy nhiên, nếu mã này chạy trong khi cửa sổ UIAlert hiển thị convertRect trả về khung điều chỉnh với kích thước (ít nhất là chiều rộng) bằng 0. Bạn có nghĩ gì về điều đó không?
Electro-Bunny

Ah. An UIAlertViewsẽ tự chèn vào dưới dạng khung nhìn rootViewControll của keyWindow. Tôi có logic tránh trường hợp góc vì nếu chế độ xem cảnh báo được bật lên, người dùng không thể tương tác với bàn phím, do đó thường không cần phải lấy khung bàn phím tại thời điểm đó.
memmons

Cảm ơn vì sự sáng suốt. Tôi đã sử dụng kỹ thuật của bạn trong một đơn quảng cáo banner. Đó là một cách đơn giản và hay để nói với quảng cáo api kích thước của khung màn hình cho một quảng cáo mới. Vì tôi sẽ không thể loại trừ lẫn nhau các quảng cáo biểu ngữ và UIAlert, tôi có thể sẽ quay lại phát hiện phong cảnh so với chân dung và chuyển đổi vũ lực x / y khi cần thiết.
Electro-Bunny

9

Chúng tôi cũng phải xem xét định hướng của thiết bị:

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

Giải pháp tốt Tôi đã làm điều này để giúp ứng dụng iPad của tôi hoạt động theo chiều ngang từ bên trong bộ điều khiển chế độ xem được nhúng khi trình bày một chế độ VC.
StackRunner

8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);

5

Ở đây tôi đã cập nhật cho swift 3

applicationFrame không dùng nữa từ iOS 9

Trong swift ba họ đã loại bỏ () và họ đã thay đổi một vài quy ước đặt tên, bạn có thể tham khảo tại đây Liên kết

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

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

4

Câu trả lời hiện đại:

nếu ứng dụng của bạn hỗ trợ chế độ xem tách trên iPad, vấn đề này sẽ trở nên hơi phức tạp. Bạn cần kích thước cửa sổ, không phải màn hình, có thể chứa 2 ứng dụng. Kích thước cửa sổ cũng có thể thay đổi trong khi chạy.

Sử dụng kích thước cửa sổ chính của ứng dụng:

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

Lưu ý: Phương pháp trên có thể nhận giá trị sai trước khi cửa sổ trở thành cửa sổ chính khi khởi động. Nếu bạn chỉ cần chiều rộng, phương pháp dưới đây rất được khuyến khích :

UIApplication.shared.statusBarFrame.width

Giải pháp cũ sử dụng UIScreen.main.boundssẽ trả về giới hạn của thiết bị. Nếu ứng dụng của bạn chạy ở chế độ xem tách, nó có kích thước sai.

self.view.window trong câu trả lời nóng nhất có thể bị sai kích thước khi ứng dụng chứa 2 cửa sổ trở lên và cửa sổ có kích thước nhỏ.


4

Sử dụng những Structsthông tin này để biết thông tin hữu ích về thiết bị hiện tại trong 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

Nếu bạn muốn chiều rộng / chiều cao màn hình bất kể hướng của thiết bị (tốt cho việc định cỡ chân dung chỉ xem các bộ điều khiển được khởi chạy từ hướng ngang):

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

[UIScreen mainScreen] .nativeBound <- Từ các tài liệu -> Hình chữ nhật giới hạn của màn hình vật lý, được đo bằng pixel. Hình chữ nhật này dựa trên thiết bị theo hướng dọc. Giá trị này không thay đổi khi thiết bị quay.


2

Đây là một cách Swift để có được kích thước màn hình:

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
}

Chúng được bao gồm như là một chức năng tiêu chuẩn trong:

https://github.com/goktugyil/EZSwiftExtensions


1

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


1

nhanh chóng 3.0

cho chiều rộng

UIScreen.main.bounds.size.width

cho chiều cao

UIScreen.main.bounds.size.height

-2

Bạn có thể đặt các macro này trong tệp pch của mình và được sử dụng ở mọi nơi trong dự án bằng cách sử dụng "SCREEN_WIDTH"

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

và "SCREEN_HEIGHT"

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

Ví dụ về việc sử dụng:

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

Bạn có thể vui lòng thụt mã theo định dạng markdown không? Hiện tại, điều này đã được đánh dấu là "chất lượng thấp" bởi người dùng trong cộng đồng trong hàng đánh giá.
Manoj Kumar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.