İOS'ta ekran genişliği ve yüksekliği nasıl elde edilir?


506

İOS'ta ekranın boyutları nasıl elde edilebilir?

Şu anda kullanıyorum:

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

içinde viewWillAppear:vewillAnimateRotationToInterfaceOrientation:duration:

İlk kez tüm ekran boyutunu elde ediyorum. İkinci kez ekran eksi nav bar olsun.

Yanıtlar:


1063

İOS'ta ekranın boyutları nasıl elde edilebilir?

Gönderdiğiniz kodla ilgili sorun, ekranın boyutuna uyması için görünüm boyutuna güvenmenizdir ve gördüğünüz gibi durum her zaman böyle değildir. Ekran boyutuna ihtiyacınız varsa, ekranın kendisini temsil eden nesneye şöyle bakmalısınız:

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

Bölünmüş görünüm için güncelleme: Yorumlarda Dmitry sordu:

Bölünmüş görünümde ekranın boyutunu nasıl alabilirim?

Yukarıda verilen kod, bölünmüş ekran modunda bile ekranın boyutunu bildirir. Bölünmüş ekran modunu kullandığınızda, uygulamanızın penceresi değişir. Yukarıdaki kod size beklediğiniz bilgileri vermezse, OP gibi, yanlış nesneye bakıyorsunuz demektir. Bu durumda, ekran yerine pencereye şöyle bakmalısınız:

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

Hızlı 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
Yönlendirme gerçekten görünüm denetleyicisi düzeyinde yönetilir. Bir göz atın Görünüm Denetçisi'nin Arayüz Yönünü yönetme . Evet, görünüm denetleyicinizin interfaceOrientation özelliğine bakın. BTW, ekran boyutunu sordunuz, bu yüzden size gösterdim, ancak içeriğinizi görüntülemek için ne yaptığınıza bağlı olarak muhtemelen pencerenin sınırlarını veya ekranın uygulama çerçevesini kullanmalısınız.
Caleb

2
bunun dolgu olmadan tam ekran genişliğini döndürdüğünü unutmayın . Çoğu öğe için 'kullanılabilir' alan elde etmek için uygulamanızın dolgusunu (genellikle her iki tarafta 20) çıkarın
Nick Daugherty

2
@NickDaugherty Evet, mesele bu - OP ekran boyutlarını istedi. Nesneleri ekrana yerleştirdiğiniz yer tamamen size bağlıdır ve ne tür bir uygulama oluşturduğunuza bağlıdır. Örneğin bir fotoğraf veya oyun arayüzü görüntülüyorsanız, hiç dolgu istemeyebilirsiniz.
Caleb

3
Ancak bunun nokta cinsinden ölçülen bir değer döndürdüğünü unutmayın. Dolayısıyla, ekran çözünürlüğünü piksel cinsinden bekliyorsanız, sonuç yanlış olur ve sonucu ile çarpmanız gerekir [UIScreen scale].
Robotbugs

3
Biri yana olduğuna işaret bir CGRect negatif eni veya boyu da olabilir , kullandığımız gerekir CGRectGetWidth()ve CGRectGetHeight()bunun yerine, doğrudan erişim için sizedikdörtgen içinde yer alan. Ekran dikdörtgeni ile ilgili bir sorun olacağını düşünmüyorum, ancak bunun farkında olması gereken bir şey olduğunu düşünüyorum.
Caleb

64

Dikkatli olun, [UIScreen mainScreen] durum çubuğu da içerir, uygulamanız için çerçeveyi almak istiyorsanız (durum çubuğu hariç) kullanmalısınız

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

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

4
ios 9.0'da kullanımdan kaldırıldı
Zakaria Darwish

6
applicationFrame kullanımdan kaldırıldığından,return [[UIScreen mainScreen] bounds].size.width;
lizzy81

44

Yukarıdaki Objective-C cevaplarından bazılarını Swift koduna çevirdim. Her çeviri orijinal cevaba referansla yapılır.

Ana cevap

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

Basit İşlev Cevabı

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

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

Cihaz Yönü Cevabı

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
}

Günlük Cevabı

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

Günlük Yanıtında bir yazım hatası varmış gibi görünüyor: UIScreen.mainScreen (). Bounds.size.width olmalı mı? ".Bounds" olmadan bir derleme hatası alıyorum.
taş

@skypecakes Cevabı ".bounds" içerecek şekilde düzelttim. Geri dönüşünüz için teşekkür ederiz.
Martin Woolstenhulme

applicationFrame, iOS 9 ve sonraki sürümlerinde kullanımdan kaldırılmıştır, bunun yerinereturn UIScreen.mainScreen().bounds].size.width
Suhaib

39

Daha önce bu kolaylık yöntemlerini kullandım:

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

Güzel bir çözüm, ancak temp'in tanımlanmamış bir kökene sahip olduğuna dikkat edin.
szemian

4
Varsayılan olarak 0,0 alıyor musunuz? FullScreenRect'e giriş yaptığımda bana şunu verdi: {{8.03294e-35, 3.09816e-40}, {480, 320}}. CGRect temp = CGRectZero ile başlatılmayı seçtim;
szemian

1
UIInterfaceOrientationIsLandscape, UIDevice'den döndürülebilecek 'UIDeviceOrientationFaceUp' ve 'UIDeviceOrientationFaceDown' öğelerini işlemez.
Andriy

6
Durum çubuğuyla ilgilenen screen.bounds yerine screen.applicationFrame özelliğini kullanmak isteyebilirsiniz.
Geraud.ch

(A SplitView tam ekran modals) applicationFrame bir doğru çıkarılır durum çubuğunda ile Dosnt dönüş çerçevesi bazı durumlarda dışarı dönüşler
Luke McNeice

15

Bunun eski bir yazı olduğunu anlıyorum, ancak bazen # sabitleri bu gibi tanımlamak için yararlı buluyorum, bu yüzden endişelenmem gerekmiyor:

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

Yukarıdaki sabit, cihazın yönü ne olursa olsun doğru boyutu döndürmelidir. Ardından boyutları elde etmek şu kadar basit:

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

Makro, en iyi yanıt gibi göründüğü için AnswerBot'un yanıtına dayandırabilirsiniz.
griotspeak

13

Bu sizin cihaz büyüklüğünü elde etmek için çok, çok kolay hem de hesaba yönelim içine take:

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

Merhaba, ben bir iPad manzara sadece app viewDidLoad bunu kullanın, ilk kez doğru değeri almak için herhangi bir nedeni var, daha sonra değer daha sonra her yükte 'çevirir', yani ilk peyzaj görünümü olarak okur, sonra ben uzağa gidip görünüme geri dönün ve yön değişikliği yapılmadan bile portre olarak okunuyor mu? Teşekkürler
craigk

@LukeMcneice Üretim kodumda bir çerçevenin bulunduğundan emin olmak için bir onaycım var ... Henüz bu onaylamada başarısız oldum. RootView ve originalFrame için ne döndürülüyor?
memmons

Yönü düzeltilmiş genişlik / yükseklik elde etmek için tek birtonda bu tekniği kullanıyorum. Ancak, bu kod, convertRect'i gösteren bir UIAlert penceresi 0 boyutunda (en az genişlik) 0'a ayarlanmış bir çerçeve döndürürse çalışır. Herhangi bir düşünce bununla ne oluyor?
Electro-Bunny

Ah. Bir UIAlertViewkendisini keyWindow'un rootViewController görünümü olarak ekler. Bir uyarı görünümü varsa, kullanıcı klavyeyle etkileşime giremeyeceği için köşe kasasını önleyen mantığım var, bu yüzden genellikle o zaman klavye çerçevesini yakalamaya gerek yok.
Nisan'ta 16

İçgörü için teşekkürler. Tekniğinizi banner reklam singletonunda kullanıyordum. Yeni bir reklam için reklam çerçevesine ekran çerçevesinin boyutunu söylemenin basit ve güzel bir yoluydu. Banner reklamları karşılıklı olarak hariç tutamayacağım ve UIAlert'ın x / y'yi gerektiği gibi dikey ve kaba kuvvet değiştirmeye karşı manzara algılamaya geri döneceğim.
Electro-Bunny

9

Cihazın yönünü de dikkate almalıyız:

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

İyi bir çözüm, bir modal VC sunarken iPad uygulamamın gömülü görünüm denetleyicisinin içinden manzara içinde çalışmasını sağlamak için yaptım.
StackRunner

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

5

Burada hızlı 3 için güncellendi

applicationFrame , iOS 9'dan kullanımdan kaldırıldı

Hızlı üçte kaldırıldılar () ve birkaç adlandırma kuralını değiştirdiler, buraya başvurabilirsiniz Bağlantı

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

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

4

Modern cevap:

uygulamanız iPad'de bölünmüş görünümü destekliyorsa, bu sorun biraz karmaşıklaşır. 2 uygulama içerebilecek ekranın değil pencerenin boyutuna ihtiyacınız vardır. Pencerenin boyutu çalışırken de değişebilir.

Uygulamanın ana penceresinin boyutunu kullan:

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

Not: Yukarıdaki yöntem, başlatma sırasında pencerenin anahtar pencere haline gelmesinden önce yanlış değer alabilir. sadece genişliğe ihtiyacınız varsa, aşağıdaki yöntem çok önerilir :

UIApplication.shared.statusBarFrame.width

Eski çözüm UIScreen.main.bounds, cihazın sınırlarını döndürür. Uygulamanız bölünmüş görünüm modunda çalışıyorsa yanlış boyutlara sahip olur.

self.view.window sıcak cevap uygulama 2 veya daha fazla pencere içerdiğinde ve pencere küçük boyutu olduğunda yanlış boyut alabilirsiniz.


4

StructsSwift 3.0'daki geçerli cihaz hakkında yararlı bilgiler bilmek için bunları kullanın

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

Cihaz yönüne bakılmaksızın ekran genişliği / yüksekliği istiyorsanız (yalnızca dikey boyutlandırma için yatay yönlerden başlatılan görüntüleme denetleyicileri için iyi):

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

[UIScreen mainScreen] .nativeBounds <- Dokümanlardan -> Fiziksel ekranın piksel cinsinden ölçülen sınırlayıcı dikdörtgeni. Bu dikdörtgen cihaza dikey olarak yerleştirilir. Bu değer cihaz döndükçe değişmez.


2

İşte ekran boyutlarını almanın hızlı bir yolu:

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
}

Bunlar standart fonksiyon olarak dahil edilmiştir:

https://github.com/goktugyil/EZSwiftExtensions


1

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


1

hızlı 3.0

genişlik için

UIScreen.main.bounds.size.width

boy için

UIScreen.main.bounds.size.height

-2

Bu makroları pch dosyanıza yerleştirebilir ve "SCREEN_WIDTH" kullanarak projenin herhangi bir yerinde kullanabilirsiniz

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

ve "SCREEN_HEIGHT"

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

Kullanım örneği:

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

Lütfen kodunuzu markdown biçimine göre girintili hale getirebilir misiniz? Şu anda bu, inceleme sırasında topluluk kullanıcıları tarafından "düşük kalite" olarak işaretlendi.
Manoj Kumar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.