Як отримати ширину та висоту екрана в iOS?


506

Як можна отримати розміри екрана в iOS?

В даний час я використовую:

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

в viewWillAppear:іwillAnimateRotationToInterfaceOrientation:duration:

Перший раз я отримую весь розмір екрана. Вдруге я отримую екран мінус панель навігації.

Відповіді:


1063

Як можна отримати розміри екрана в iOS?

Проблема з опублікованим вами кодом полягає в тому, що ви розраховуєте на розмір перегляду, який відповідає розміру екрана, і, як ви бачили, це не завжди так. Якщо вам потрібен розмір екрана, ви повинні подивитися на об'єкт, що представляє сам екран, як це:

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

Оновлення для розділеного перегляду: У коментарях Дмитро запитав:

Як я можу отримати розмір екрана в розділеному вигляді?

Код, наведений вище, повідомляє про розмір екрана, навіть у режимі розділеного екрана. Під час використання режиму розділеного екрана вікно програми змінюється. Якщо наведений вище код не дає вам очікуваної інформації, то, як і ОП, ви дивитесь на неправильний об’єкт. Однак у цьому випадку слід дивитись у вікно замість екрана:

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

7
Орієнтацією реально керувати на рівні контролера перегляду. Погляньте на Управління інтерфейсом орієнтації контролера подання . Так що так, подивіться на властивість інтерфейсу диспетчера переглядуОрієнтація. До речі, ви запитували про розмір екрана, тож це я вам показав, але для відображення вмісту ви, мабуть, повинні використовувати межі вікна або програму екранаFrame, залежно від того, що ви робите.
Калеб

2
корисно зазначити, що це повертає повну ширину екрану без прокладки. Просто відніміть підкладку вашої програми (як правило, 20 на кожній стороні) від цих результатів, щоб отримати "корисну" область для більшості елементів
Нік Даггерті

2
@NickDaugherty Так, справа - ОП хотів розмірів екрана. Те, де ви розміщуєте об’єкти на екрані, залежить лише від того, який саме додаток ви будуєте. Наприклад, якщо ви показуєте фотографію чи ігровий інтерфейс, можливо, вам взагалі не потрібна будь-яка набивка.
Калеб

3
Однак зауважте, що це повертає значення, виміряне в балах. Отже, якщо ви очікували роздільної здатності екрана в пікселях, результат був би невірним, і ви повинні помножити результат на [UIScreen scale].
Robotbugs

3
Хтось зазначив, що оскільки CGRect може мати негативну ширину чи висоту , ми повинні використовувати CGRectGetWidth()та CGRectGetHeight()замість прямого доступу до sizeполя в прямокутнику. Я не думаю, що це колись може бути проблемою щодо прямокутника екрану, але я вважаю, що це слід знати.
Калеб

64

Обережно, [UIScreen mainScreen] також містить рядок стану, якщо ви хочете отримати кадр для вашої програми (виключаючи рядок стану), ви повинні використовувати

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

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

4
застаріло в ios 9.0
Закарія Дарвіш

6
Оскільки return [[UIScreen mainScreen] bounds].size.width;
додатокFrame

44

Я переклав деякі з перерахованих вище відповідей Objective-C у код Swift. Кожен переклад ведеться з посиланням на оригінальну відповідь.

Основна відповідь

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

Проста функція відповіді

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

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

Відповідь орієнтації на пристрій

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
}

Вхід відповіді

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().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
Suhaib

39

Я раніше використовував ці методи зручності:

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

Гарне рішення, але будьте уважні, що темп, здається, має невизначене походження.
szemian

4
Ви отримуєте 0,0 за замовчуванням? Коли я зареєстрував fullScreenRect, він отримав: {{8.03294e-35, 3.09816e-40}, {480, 320}}. Я вибрав ініціалізацію з CGRect temp = CGRectZero;
шемян

1
UIInterfaceOrientationIsLandscape не обробляє 'UIDeviceOrientationFaceUp' та 'UIDeviceOrientationFaceDown', які можуть бути повернуті з UIDevice.
Андрій

6
Можливо, ви хочете використовувати властивість screen.applicationFrame замість screen.bounds, яка піклується про рядок стану.
Geraud.ch

Виявляється в деяких випадках applicationFrame не повертає кадр з правильно віднятим рядком стану (повноекранні модалі з розділеного перегляду)
Luke Mcneice

15

Я усвідомлюю, що це стара публікація, але іноді мені здається корисним #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, оскільки це здається найкращою відповіддю.
griotspeak

13

Отримати розмір вашого пристрою , а також врахувати орієнтацію дуже, дуже просто :

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

Привіт, я використовую це в viewDidLoad на додатку для пейзажу iPad, чи є причина, чому воно отримує правильне значення вперше, потім значення "перевертається" при кожному завантаженні після того, тобто воно зчитує його як перший погляд на ландшафті, потім я перейдіть назад і назад до виду, і, здається, читайте його як портрет, навіть не змінивши орієнтацію? Спасибі
craigk

@LukeMcneice У своєму виробничому коді я маю твердження, щоб переконатися, що кадр знайдений ... Я ще не мав цього затвердження. Що повертається для rootView та originalFrame?
пам’ятки

Я використовую цю техніку в одиночному режимі, щоб отримати коригування орієнтації по ширині / висоті. Однак якщо цей код запускається під час вікна UIAlert, що показує, що файлReReVet повертає коригуванийFrame з розміром (шириною не менше) 0. Будь-які думки, що з цим відбувається?
Електро-Зайчик

Ага. А UIAlertViewбуде вставляти себе як перегляд rootViewController keyWindow. У мене є логіка, яка дозволяє уникнути кутового випадку, тому що, якщо перегляд тривог увімкнено, користувач не може взаємодіяти з клавіатурою, тому зазвичай не потрібно захоплювати рамку клавіатури на той час.
пам’ятки

Дякуємо за розуміння. Я використовував вашу техніку в банері, синглтон. Це був простий і приємний спосіб сказати рекламному розміру розмір рамки екрана для нової реклами. Оскільки я не зможу взаємно виключати рекламні банери та UIAlert, я, швидше за все, повернуться до виявлення ландшафту проти портретного та грубої сили перемикання x / y у міру необхідності.
Електро-Зайчик

9

Ми також повинні врахувати орієнтацію пристрою:

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 працював у ландшафтному режимі зсередини вбудованого контролера перегляду при поданні модального ЦК.
StackRunner


5

Ось я оновив для швидкого 3

applicationFrame застарілий з iOS 9

Швидко три вони видалили () і вони змінили декілька умов іменування, ви можете посилатися тут Посилання

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

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

4

Сучасна відповідь:

якщо ваша програма підтримує розділений вигляд на iPad, ця проблема стає дещо складною. Вам потрібен розмір вікна, а не екран, який може містити 2 програми. Розмір вікна також може змінюватися під час роботи.

Використовуйте розмір головного вікна програми:

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

Примітка. Наведений вище метод може отримати неправильне значення, перш ніж вікно стане ключовим вікном при запуску. якщо вам потрібна лише ширина, дуже рекомендується описаний нижче спосіб :

UIApplication.shared.statusBarFrame.width

Старе рішення з використанням UIScreen.main.boundsповерне межі пристрою. Якщо ваша програма працює в режимі розділеного перегляду, вона отримує неправильні параметри.

self.view.window у найгарячішій відповіді може бути неправильний розмір, якщо програма містить 2 або більше вікон, і вікно має невеликий розмір.


4

Скористайтеся ними, 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)

}

3

Якщо ви хочете ширину / висоту екрана незалежно від орієнтації пристрою (добре підходить для розміщення контролерів лише виду портрета, що запускаються з ландшафтних орієнтацій):

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

[UIScreen mainScreen] .nativeBounds <- Від документів -> Обмежувальний прямокутник фізичного екрана, виміряний у пікселях. Цей прямокутник заснований на пристрої в портретній орієнтації. Це значення не змінюється під час обертання пристрою.


2

Ось швидкий спосіб отримати розміри екрана:

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



1

швидкий 3.0

по ширині

UIScreen.main.bounds.size.width

за висотою

UIScreen.main.bounds.size.height

-2

Ви можете розмістити ці макроси у вашому файлі 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;

Чи можете ви просити відмітити свій код відповідно до формату розмітки? Наразі користувачі спільноти помітили це як "низьку якість" у черзі на огляд.
Маной Кумар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.