Bagaimana cara mendapatkan lebar dan tinggi layar di iOS?

506

Bagaimana seseorang bisa mendapatkan dimensi layar di iOS?

Saat ini, saya menggunakan:

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

di viewWillAppear:danwillAnimateRotationToInterfaceOrientation:duration:

Pertama kali saya mendapatkan seluruh ukuran layar. Kedua kalinya saya mendapatkan layar minus bilah nav.

griotspeak
sumber

Jawaban:

1063

Bagaimana seseorang bisa mendapatkan dimensi layar di iOS?

Masalah dengan kode yang Anda poskan adalah bahwa Anda mengandalkan ukuran tampilan untuk mencocokkan dengan layar, dan seperti yang Anda lihat tidak selalu demikian. Jika Anda membutuhkan ukuran layar, Anda harus melihat objek yang mewakili layar itu sendiri, seperti ini:

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

Pembaruan untuk tampilan split: Dalam komentar, Dmitry bertanya:

Bagaimana saya bisa mendapatkan ukuran layar dalam tampilan split?

Kode yang diberikan di atas melaporkan ukuran layar, bahkan dalam mode layar terbagi. Saat Anda menggunakan mode layar terbagi, jendela aplikasi Anda berubah. Jika kode di atas tidak memberi Anda informasi yang Anda harapkan, maka seperti OP, Anda melihat objek yang salah. Namun, dalam hal ini, Anda harus melihat jendela alih-alih layar, seperti ini:

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

Cepat 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
Caleb
sumber
7
Orientasi benar-benar dikelola pada level controller tampilan. Lihatlah Mengelola Orientasi Antarmuka Tampilan Pengontrol . Jadi ya, lihat properti interfaceOrientation dari view controller Anda. BTW, Anda bertanya tentang ukuran layar, jadi itulah yang saya perlihatkan kepada Anda, tetapi untuk menampilkan konten Anda, Anda mungkin harus menggunakan batas jendela atau bingkai aplikasi layar, tergantung pada apa yang Anda lakukan.
Caleb
2
Penting untuk dicatat bahwa ini mengembalikan lebar layar penuh tanpa bantalan. Cukup kurangi bantalan aplikasi Anda (biasanya 20 di setiap sisi) dari hasil ini untuk mendapatkan ruang 'dapat digunakan' untuk sebagian besar elemen
Nick Daugherty
2
@NickDaugherty Ya, itu intinya - OP menginginkan dimensi layar. Di mana Anda meletakkan objek di layar sepenuhnya terserah Anda dan tergantung pada jenis aplikasi yang Anda buat. Jika Anda menampilkan foto atau antarmuka game, misalnya, Anda mungkin tidak ingin bantalan sama sekali.
Caleb
3
Namun perlu dicatat bahwa ini mengembalikan nilai yang diukur dalam poin. Jadi jika Anda mengharapkan resolusi layar dalam piksel, hasilnya akan salah, dan Anda harus mengalikan hasilnya dengan [UIScreen scale].
Robotbugs
3
Seseorang menunjukkan bahwa karena CGRect dapat memiliki lebar atau tinggi negatif , kita harus menggunakan CGRectGetWidth()dan CGRectGetHeight()bukannya langsung mengakses sizebidang dalam persegi panjang. Saya tidak berpikir itu akan pernah menjadi masalah sehubungan dengan persegi panjang layar, tapi saya kira itu sesuatu yang harus diperhatikan.
Caleb
64

Hati-hati, [UIScreen mainScreen] juga mengandung bilah status, jika Anda ingin mengambil bingkai untuk aplikasi Anda (tidak termasuk bilah status), Anda harus menggunakan

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

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}
Ege Akpinar
sumber
4
usang di ios 9.0
Zakaria Darwish
6
karena applicationFrame sudah tidak digunakan lagi, ganti denganreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81
44

Saya telah menerjemahkan beberapa jawaban Objective-C di atas ke dalam kode Swift. Setiap terjemahan diproses dengan referensi ke jawaban asli.

Jawaban utama

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

Fungsi Jawaban Sederhana

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

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

Jawaban Orientasi Perangkat

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
}

Jawab Log

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")
Martin Woolstenhulme
sumber
Sepertinya ada salah ketik di Jawaban Log: Haruskah itu UIScreen.mainScreen (). Bounds.size.width? Saya mendapatkan kesalahan kompilasi tanpa ".bounds".
batu
@skypecakes Saya sudah memperbaiki jawaban untuk menyertakan ".bounds". Terima kasih untuk umpan baliknya.
Martin Woolstenhulme
applicationFrame sudah usang di iOS 9 dan di atasnya, ganti denganreturn UIScreen.mainScreen().bounds].size.width
Suhaib
39

Saya telah menggunakan metode kenyamanan ini sebelumnya:

- (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;
} 
Luke Mcneice
sumber
Solusi yang bagus, tetapi berhati-hatilah karena temp tampaknya tidak memiliki asal yang jelas.
szemian
4
Apakah Anda mendapatkan 0,0 secara default? Ketika saya login fullScreenRect, itu memberi saya: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Saya memilih untuk menginisialisasi dengan CGRect temp = CGRectZero;
szemian
1
UIInterfaceOrientationIsLandscape tidak menangani 'UIDeviceOrientationFaceUp' dan 'UIDeviceOrientationFaceDown' yang dapat dikembalikan dari UIDevice.
Andriy
6
Anda mungkin ingin menggunakan layar properti.aplikasi Bingkai bukan layar.batas yang mengurus bilah status.
Geraud.ch
Ternyata dalam beberapa kasus applicationFrame dos't return frame dengan status bar dikurangi dengan benar (full screen modals dari splitview)
Luke Mcneice
15

Saya menyadari bahwa ini adalah pos lama, tetapi kadang-kadang saya merasa berguna untuk mendefinisikan konstanta seperti ini sehingga saya tidak perlu khawatir tentang hal itu:

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

Konstanta di atas harus mengembalikan ukuran yang benar tidak peduli orientasi perangkat. Maka mendapatkan dimensi sesederhana:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;
Pengguna Acak
sumber
Anda mungkin ingin mendasarkan makro pada jawaban AnswerBot karena itu sepertinya jawaban terbaik.
griotspeak
13

Sangat, sangat mudah untuk mendapatkan ukuran perangkat Anda serta memperhitungkan orientasinya:

// 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];
memmons
sumber
Hai, saya menggunakan ini di viewDidLoad pada aplikasi hanya lanskap iPad, apakah ada alasan mengapa ia mendapatkan nilai yang benar pertama kali, kemudian nilai 'membalik' pada setiap beban setelah daripada, yaitu membacanya sebagai tampilan pertama lanscape, lalu saya menavigasi dan kembali ke tampilan dan tampaknya membacanya sebagai potret meskipun tidak ada perubahan orientasi yang dibuat? Terima kasih
craigk
@ LukasMcneice Dalam kode produksi saya, saya memiliki pernyataan untuk memastikan bahwa frame ditemukan ... Saya belum memiliki pernyataan yang gagal. Apa yang dikembalikan untuk rootView dan originalFrame?
memmons
Saya menggunakan teknik ini dalam singleton untuk mendapatkan orientasi-koreksi lebar / tinggi. Namun, jika kode ini berjalan saat jendela UIAlert yang memperlihatkan convertRect mengembalikan adjustedFrame dengan ukuran (setidaknya lebar) dari 0. Adakah pemikiran apa yang terjadi dengan itu?
Electro-Bunny
Ah. Sebuah UIAlertViewakan memasukkan dirinya sebagai tampilan rootViewController keyWindow. Saya memiliki logika yang menghindari kasing sudut karena jika tampilan lansiran naik, pengguna tidak dapat berinteraksi dengan keyboard, jadi biasanya tidak perlu mengambil bingkai keyboard saat itu.
memmons
Terima kasih atas wawasannya. Saya menggunakan teknik Anda dalam iklan banner tunggal. Itu adalah cara yang sederhana dan baik untuk memberitahu api iklan ukuran bingkai layar untuk iklan baru. Karena saya tidak akan dapat saling mengecualikan iklan banner dan UIAlert, saya kemungkinan besar akan kembali mendeteksi lansekap vs potret dan penggantian tenaga kasar x / y sesuai kebutuhan.
Electro-Bunny
9

Kami juga harus mempertimbangkan orientasi perangkat:

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;
}
Oleh Kudinov
sumber
Solusi yang bagus Saya melakukan ini untuk membuat aplikasi iPad saya bekerja di lanskap dari dalam pengontrol tampilan tertanam ketika menghadirkan VC modal.
StackRunner
8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);
Gaurav Gilani
sumber
5

Di sini saya telah memperbarui untuk 3 cepat

applicationFrame sudah tidak digunakan lagi di iOS 9

Dalam tiga cepat mereka telah menghapus () dan mereka telah mengubah beberapa konvensi penamaan, Anda dapat merujuk di sini Tautan

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

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

Jawaban modern:

jika aplikasi Anda mendukung tampilan split di iPad, masalah ini menjadi sedikit rumit. Anda perlu ukuran jendela, bukan layar, yang mungkin berisi 2 aplikasi. Ukuran jendela juga dapat bervariasi saat berjalan.

Gunakan ukuran jendela utama aplikasi:

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

Catatan: Metode di atas mungkin mendapatkan nilai yang salah sebelum jendela menjadi jendela kunci saat memulai. jika Anda hanya membutuhkan lebar, metode di bawah ini sangat disarankan :

UIApplication.shared.statusBarFrame.width

Solusi lama menggunakan UIScreen.main.boundsakan mengembalikan batas perangkat. Jika aplikasi Anda berjalan dalam mode tampilan terpisah, itu mendapatkan dimensi yang salah.

self.view.window dalam jawaban terpanas mungkin mendapatkan ukuran yang salah ketika aplikasi berisi 2 atau lebih jendela dan ukuran jendela kecil.

cuti
sumber
4

Manfaatkan ini Structsuntuk mengetahui info berguna tentang perangkat saat ini di 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)

}
badhanganesh
sumber
3

Jika Anda ingin lebar / tinggi layar terlepas dari orientasi perangkat (baik untuk ukuran potret, hanya pengontrol tampilan yang diluncurkan dari orientasi lanskap):

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

[UIScreen mainScreen] .nativeBounds <- Dari dokumen -> Persegi panjang pembatas dari layar fisik, diukur dalam piksel. Persegi panjang ini didasarkan pada perangkat dalam orientasi potret-up. Nilai ini tidak berubah ketika perangkat berputar.

John Erck
sumber
2

Berikut adalah cara cepat untuk mendapatkan ukuran layar:

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
}

Ini termasuk sebagai fungsi standar dalam:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
sumber
1

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

Himanshu jamnani
sumber
1

cepat 3.0

untuk lebar

UIScreen.main.bounds.size.width

untuk ketinggian

UIScreen.main.bounds.size.height
Amul4608
sumber
-2

Anda dapat menempatkan makro ini di file pch Anda dan digunakan di mana saja dalam proyek dengan menggunakan "SCREEN_WIDTH"

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

dan "SCREEN_HEIGHT"

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

Contoh menggunakan:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;
Anny
sumber
Bisakah Anda indentasi kode Anda sesuai dengan format penurunan harga? Saat ini ditandai sebagai "kualitas rendah" oleh pengguna komunitas dalam antrian peninjauan.
Manoj Kumar