วิธีรับความกว้างและความสูงของหน้าจอใน 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;

อัปเดตสำหรับมุมมองแยก:ในความคิดเห็น Dmitry ถาม:

ฉันจะทำให้ขนาดของหน้าจอเป็นมุมมองแบบแยกได้อย่างไร

รหัสที่ระบุด้านบนรายงานขนาดของหน้าจอแม้ในโหมดแยกหน้าจอ เมื่อคุณใช้โหมดแบ่งหน้าจอหน้าต่างแอพของคุณจะเปลี่ยนไป หากรหัสด้านบนไม่ให้ข้อมูลที่คุณคาดหวังเช่นเดียวกับ OP คุณจะเห็นวัตถุที่ผิด ในกรณีนี้คุณควรดูที่หน้าต่างแทนที่จะเป็นหน้าจอดังนี้:

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
มีการจัดการการวางแนวในระดับตัวควบคุมมุมมอง ลองดูที่การจัดการดูควบคุมของอินเตอร์เฟซการปฐมนิเทศ ดังนั้นใช่ดูที่คุณสมบัติ interfaceOrientation ของคอนโทรลเลอร์คอนโทรลเลอร์ BTW คุณถามเกี่ยวกับขนาดหน้าจอดังนั้นนั่นคือสิ่งที่ฉันแสดงให้คุณ แต่สำหรับการแสดงเนื้อหาของคุณคุณควรใช้ขอบเขตของหน้าต่างหรือกรอบแอพพลิเคชันของหน้าจอขึ้นอยู่กับสิ่งที่คุณทำ
Caleb

2
มันมีประโยชน์ที่จะต้องทราบว่าสิ่งนี้จะส่งกลับความกว้างเต็มหน้าจอโดยไม่ต้องเว้นระยะ เพียงลบการเติมแอปของคุณ (โดยปกติคือ 20 แต่ละด้าน) จากผลลัพธ์เหล่านี้เพื่อให้ได้พื้นที่ 'ใช้งานได้' สำหรับองค์ประกอบส่วนใหญ่
Nick Daugherty

2
@NickDaugherty ใช่นั่นคือประเด็น - OP ต้องการขนาดหน้าจอ ตำแหน่งที่คุณวางวัตถุบนหน้าจอนั้นขึ้นอยู่กับคุณทั้งหมดและขึ้นอยู่กับประเภทของแอปที่คุณกำลังสร้าง หากคุณกำลังแสดงรูปถ่ายหรืออินเทอร์เฟซเกมคุณอาจไม่ต้องการใช้ช่องว่างภายในเลย
คาเลบ

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
Zakaria Darwish

6
เนื่องจาก applicationFrame เลิกใช้แล้วให้แทนที่ด้วยreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81

44

ฉันแปลบางคำตอบของ Objective-C ข้างต้นเป็น Swift code การแปลแต่ละครั้งจะดำเนินการโดยอ้างอิงกับคำตอบดั้งเดิม

คำตอบหลัก

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" ขอบคุณสำหรับความคิดเห็น.
Martin Woolstenhulme

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

1
UIInterfaceOrientationIsL landscape ไม่ได้จัดการ 'UIDeviceOrientationFaceUp' และ 'UIDeviceOrientationFaceDown' ซึ่งอาจถูกส่งคืนจาก UIDevice
Andriy

6
คุณอาจต้องการใช้คุณสมบัติ screen.applicationFrame แทน screen.bounds ซึ่งดูแลแถบสถานะ
Geraud.ch

ปรากฎในบางกรณีแอปพลิเคชั่นกรอบ dos ไม่คืนค่าเฟรมด้วยแถบสถานะที่ถูกลบอย่างถูกต้อง (โมดัลแบบเต็มหน้าจอจากมุมมองแยก)
Luke Mcneice

15

ฉันรู้ว่านี่เป็นบทความเก่า แต่บางครั้งฉันพบว่ามีประโยชน์สำหรับ #define constants เช่นนี้ดังนั้นฉันจึงไม่ต้องกังวลกับมัน:

#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 มีเหตุผลใดที่ทำให้ได้ค่าที่ถูกต้องในครั้งแรกจากนั้นค่า 'พลิก' ในทุก ๆ โหลดหลังจากนั้นคืออ่านเป็นมุมมองแรกของ lanscape แล้วฉัน นำทางออกไปและกลับไปที่มุมมองและดูเหมือนว่าจะอ่านเป็นแนวตั้งแม้ว่าจะไม่มีการเปลี่ยนแปลงการวางแนว ขอบคุณ
craigk

@LukeMcneice ในรหัสการผลิตของฉันฉันมีการยืนยันเพื่อให้แน่ใจว่าพบเฟรม ... ฉันยังไม่ได้ยืนยันที่ล้มเหลว สิ่งที่ส่งคืนสำหรับ rootView และ originalFrame
memmons

ฉันใช้เทคนิคนี้ในซิงเกิลตันเพื่อให้ได้ความกว้าง / ความสูงที่ปรับตามแนวแกน อย่างไรก็ตามถ้ารหัสนี้ทำงานในขณะที่หน้าต่าง UIAlert แสดงผลตอบแทนที่ได้จาก convertRect ที่ปรับแล้วกรอบที่มีขนาด (กว้างอย่างน้อยที่สุด) เท่ากับ 0 ความคิดใดที่เกิดขึ้นกับมัน?
Electro-Bunny

อา. UIAlertViewจะแทรกตัวเองเป็นมุมมอง rootViewController keyWindow ของ ฉันมีเหตุผลที่หลีกเลี่ยงกรณีมุมเพราะถ้ามุมมองการแจ้งเตือนขึ้นผู้ใช้ไม่สามารถโต้ตอบกับแป้นพิมพ์ดังนั้นโดยทั่วไปจะไม่จำเป็นต้องคว้ากรอบแป้นพิมพ์ในเวลานั้น
memmons

ขอบคุณสำหรับความเข้าใจ ฉันใช้เทคนิคของคุณในโฆษณาแบนเนอร์เดี่ยว มันเป็นวิธีที่ง่ายและดีในการบอกโฆษณาด้วยขนาดของเฟรมหน้าจอสำหรับโฆษณาใหม่ เนื่องจากฉันจะไม่สามารถยกเว้นโฆษณาแบนเนอร์ร่วมกันและ UIAlert ของฉันฉันจะถอยกลับไปตรวจจับแนวนอนกับแนวตั้งและการบังคับเปลี่ยนสัตว์เดรัจฉาน x / y ตามความจำเป็น
Electro-Bunny

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 ของฉันทำงานในแนวนอนจากภายในตัวควบคุมมุมมองแบบฝังตัวเมื่อแสดง VC แบบโมดอล
StackRunner


5

ที่นี่ฉันได้อัปเดตสำหรับswift 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;

คุณช่วยกรุณาเยื้องรหัสของคุณตามรูปแบบมาร์กดาวน์หรือไม่? ขณะนี้สิ่งนี้ถูกตั้งค่าสถานะเป็น "คุณภาพต่ำ" โดยผู้ใช้ชุมชนในคิวการตรวจสอบ
Manoj Kumar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.