วิธีการตรวจสอบ iPhone 5 (อุปกรณ์ไวด์สกรีน)


300

ฉันเพิ่งอัพเกรดเป็น XCode 4.5 GM และพบว่าตอนนี้คุณสามารถใช้ขนาด '4 "Retina' กับตัวควบคุมมุมมองของคุณในกระดานเรื่องราว

ตอนนี้ถ้าฉันต้องการสร้างแอปพลิเคชั่นที่ทำงานบนทั้ง iPhone 4 และ 5 แน่นอนว่าฉันต้องสร้างทุกหน้าต่างสองครั้ง แต่ฉันต้องตรวจสอบด้วยว่าผู้ใช้มี iPhone ที่มีหน้าจอ 3.5 "หรือ 4" แล้วหรือไม่ ดู.

ฉันควรทำอย่างไร


2
คุณไม่ต้องสร้าง "หน้าต่าง" ทุกครั้งสองครั้ง เฉพาะที่ควรจะตรงกับขนาดหน้าจอเท่านั้นที่จะต้องมีการถ่ายทอด วิธีแก้ปัญหานั้นค่อนข้างชัดเจนเพียงตรวจสอบขนาดหน้าต่างและเพิ่มการตัดสินใจตัวพิมพ์ตามขนาดที่ส่งคืน
จนถึง

1
โดยพื้นฐานแล้วมันเป็นเรื่องจริง แต่ฉันต้องการใช้ขนาดหน้าจอพิเศษในแบบที่ต่างออกไปโดยสิ้นเชิงอย่างที่คุณสามารถทำได้ด้วยหน้าจอแนวนอน
ฟินน์ไกเดน

ตรวจสอบ URL นี้: stackoverflow.com/questions/4779221/…
ios_av

ควรปรับปรุงคำถามนี้ตามอุปกรณ์ใหม่หรือไม่ เช่น "วิธีการตรวจสอบอุปกรณ์ iOS ด้วยขนาดหน้าจอ"
hfossli

คำตอบ:


467

ก่อนอื่นคุณไม่ควรสร้างมุมมองทั้งหมดใหม่เพื่อให้พอดีกับหน้าจอใหม่หรือใช้มุมมองที่แตกต่างกันสำหรับขนาดหน้าจอที่แตกต่างกัน

ใช้ความสามารถในการปรับขนาดอัตโนมัติของ iOS เพื่อให้มุมมองของคุณสามารถปรับและปรับขนาดหน้าจอใด ๆ

ไม่ยากมากอ่านเอกสารเกี่ยวกับเรื่องนั้น มันจะช่วยคุณประหยัดเวลาได้มาก

iOS 6 ยังมีคุณสมบัติใหม่เกี่ยวกับเรื่องนี้
อย่าลืมอ่านiOS 6 API changelogบนเว็บไซต์ Apple Developer
และตรวจสอบความสามารถของ iOS 6 AutoLayoutใหม่

ที่กล่าวว่าหากคุณต้องการตรวจจับ iPhone 5 จริงๆคุณสามารถพึ่งพาขนาดหน้าจอได้

[ [ UIScreen mainScreen ] bounds ].size.height

หน้าจอของ iPhone 5 มีความสูง 568.
คุณสามารถจินตนาการมาโครเพื่อทำให้ทั้งหมดนี้ง่ายขึ้น:

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

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

ดังนั้นจากนี้ไปคุณสามารถใช้มันในมาตรฐาน if / else statement:

if( IS_IPHONE_5 )
{}
else
{}

แก้ไข - ตรวจจับได้ดีขึ้น

ตามที่ระบุไว้โดยบางคนสิ่งนี้จะตรวจจับเฉพาะจอไวด์สกรีนไม่ใช่ iPhone 5 ที่แท้จริง

iPod touch รุ่นต่อไปอาจมีหน้าจอเช่นนี้ดังนั้นเราอาจใช้มาโครชุดอื่น

มาเปลี่ยนชื่อมาโคเดิมIS_WIDESCREEN:

#define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

และมาเพิ่มมาโครการตรวจจับแบบจำลอง:

#define IS_IPHONE ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] )
#define IS_IPOD   ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPod touch" ] )

ด้วยวิธีนี้เราสามารถมั่นใจได้ว่าเรามีรุ่น iPhone และจอกว้างและเราสามารถกำหนดIS_IPHONE_5มาโครใหม่ได้:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

โปรดทราบว่าตามที่ระบุไว้โดย @ LearnCocos2D มาโครนี้จะไม่ทำงานหากแอปพลิเคชันไม่ได้รับการปรับให้เหมาะกับหน้าจอ iPhone 5 (ไม่มีภาพ Default-568h@2x.png) เนื่องจากขนาดหน้าจอจะยังคงเป็น 320x480 กรณี.

ฉันไม่คิดว่านี่อาจเป็นปัญหาเพราะฉันไม่เห็นสาเหตุที่เราต้องการตรวจจับ iPhone 5 ในแอพที่ไม่ได้รับการปรับปรุงประสิทธิภาพ

สำคัญ - รองรับ iOS 8

บน iOS 8, boundsทรัพย์สินของUIScreenระดับในขณะนี้สะท้อนให้เห็นถึงการวางแนวอุปกรณ์
เห็นได้ชัดว่ารหัสก่อนหน้านี้จะไม่ทำงานนอกกรอบ

ในการแก้ไขปัญหานี้คุณสามารถใช้nativeBoundsคุณสมบัติใหม่แทนboundsเนื่องจากมันจะไม่เปลี่ยนแปลงตามการวางแนวและเนื่องจากขึ้นอยู่กับโหมดถ่ายภาพบุคคล
โปรดทราบว่าขนาดของnativeBoundsวัดเป็นพิกเซลดังนั้นสำหรับ iPhone 5 ความสูงจะเท่ากับ1136แทนที่จะเป็น 568

หากคุณกำหนดเป้าหมายเป็น iOS 7 หรือต่ำกว่าโปรดใช้การตรวจจับคุณสมบัติเนื่องจากการโทรnativeBoundsก่อน iOS 8 จะทำให้แอปของคุณ:

if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
    /* Detect using nativeBounds - iOS 8 and greater */
}
else
{
    /* Detect using bounds - iOS 7 and lower */
}

คุณสามารถปรับมาโครก่อนหน้าได้ด้วยวิธีต่อไปนี้:

#define IS_WIDESCREEN_IOS7 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IS_WIDESCREEN_IOS8 ( fabs( ( double )[ [ UIScreen mainScreen ] nativeBounds ].size.height - ( double )1136 ) < DBL_EPSILON )
#define IS_WIDESCREEN      ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_WIDESCREEN_IOS8 : IS_WIDESCREEN_IOS7 )

และถ้าคุณต้องการตรวจสอบ iPhone 6 หรือ 6 Plus ให้ใช้ขนาดหน้าจอที่เกี่ยวข้อง


7
นี่เป็นสิ่งผิดคุณจะต้องใช้#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3: โปรดทราบว่าการเปรียบเทียบDBL_EPSILONไม่จำเป็นที่นี่และการ==เปรียบเทียบจะไม่ล้มเหลว: จำเป็นต้องทำการเปรียบเทียบโดยใช้ความแตกต่างด้วยวิธีนี้หากค่าจุดลอยตัวไม่สามารถแสดงเป็นจำนวนที่แน่นอน (เช่น1.0/3.0*3.0ตัวอย่าง) อ่านบทความนี้สำหรับข้อมูลเพิ่มเติม;)
AliSoftware

2
คำตอบนี้ไม่ถูกต้อง ทำไมมันยกนิ้วให้มากมาย? คุณไม่สามารถใช้ความสูงได้เพียงเพื่อกำหนดว่าเป็นแบบจอกว้าง เพื่อน ...
OMGPOP

5
ฉันขอเพิ่ม: หากคุณต้องการให้สิ่งนี้ทำงานร่วมกับเครื่องมือจำลองใช้สิ่งนี้: #define IS_IPHONE (([[[รุ่น [UIDevice currentDevice]]] isEqualToString: @ "iPhone"]) || ([[UIDevice currentDevice] รุ่น] isEqualToString: @ "iPhone Simulator"]))
david

31
คำตอบนี้เป็นบ้า สิ่งนี้เกี่ยวกับการแนะนำไม่เปรียบเทียบการลอยตัวแบบใดแบบหนึ่ง (ซึ่งในความเป็นจริงแล้ว - และถ้าคุณรู้ว่า Apple ควรรู้ว่าจะเป็นจำนวนเต็มเสมอ) กับ == นั้นไร้สาระและซับซ้อนเกินไป นอกจากนี้ฉันคิดว่ามันจะดีกว่าถ้าใช้ UI_USER_INTERFACE_IDIOM () สำหรับการตรวจจับ iPhone เพราะทำงานได้ดีทั้งบนอุปกรณ์และเครื่องมือจำลอง (และอาจเร็วกว่าวิธี UIDevice) เพียงแค่นี้ก็ทำงานได้ดีและเป็นวิธีที่ง่ายต่อการอ่าน: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainscreen] .bounds.size.height == 568)
ริคาร์โด้ซานเชซ-Saez

232

ทดสอบและออกแบบมาสำหรับการรวมกันของ SDK และ OS:

รวดเร็ว

เพิ่มประเภท iPad iPad 2 และ iPad mini เป็นไอแพดที่ไม่ใช่เรตินา ในขณะที่ iPad Mini 2 และสูงกว่า, iPad 3, 4, iPad Air, Air 2, Air 3 และ iPad Pro 9.7 มีความละเอียดตรรกะเท่ากันที่ 1024 iPad Pro มีความยาวสูงสุด 1366 การอ้างอิง

import UIKit

public enum DisplayType {
    case unknown
    case iphone4
    case iphone5
    case iphone6
    case iphone6plus
    case iPadNonRetina
    case iPad
    case iPadProBig
    static let iphone7 = iphone6
    static let iphone7plus = iphone6plus
}

public final class Display {
    class var width:CGFloat { return UIScreen.main.bounds.size.width }
    class var height:CGFloat { return UIScreen.main.bounds.size.height }
    class var maxLength:CGFloat { return max(width, height) }
    class var minLength:CGFloat { return min(width, height) }
    class var zoomed:Bool { return UIScreen.main.nativeScale >= UIScreen.main.scale }
    class var retina:Bool { return UIScreen.main.scale >= 2.0 }
    class var phone:Bool { return UIDevice.current.userInterfaceIdiom == .phone }
    class var pad:Bool { return UIDevice.current.userInterfaceIdiom == .pad }
    class var carplay:Bool { return UIDevice.current.userInterfaceIdiom == .carPlay }
    class var tv:Bool { return UIDevice.current.userInterfaceIdiom == .tv }
    class var typeIsLike:DisplayType {
        if phone && maxLength < 568 {
            return .iphone4
        }
        else if phone && maxLength == 568 {
                return .iphone5
        }
        else if phone && maxLength == 667 {
            return .iphone6
        }
        else if phone && maxLength == 736 {
            return .iphone6plus
        }
        else if pad && !retina {
            return .iPadNonRetina
        }
        else if pad && retina && maxLength == 1024 {
            return .iPad
        }
        else if pad && maxLength == 1366 {
            return .iPadProBig
        }
        return .unknown
    }
}

ดูการทำงานของ https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

หมายเหตุ: หากเช่น iPhone 6 อยู่ในโหมดซูม UI เป็นเวอร์ชันที่ซูมขึ้นของ iPhone 5 ฟังก์ชั่นเหล่านี้ไม่ได้กำหนดประเภทของอุปกรณ์ แต่โหมดการแสดงผลทำให้ iPhone 5 เป็นผลลัพธ์ที่ต้องการในตัวอย่างนี้

Objective-C

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_ZOOMED (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

การใช้งาน: http://pastie.org/9687735

หมายเหตุ: หากเช่น iPhone 6 อยู่ในโหมดซูม UI เป็นเวอร์ชันที่ซูมขึ้นของ iPhone 5 ฟังก์ชั่นเหล่านี้ไม่ได้กำหนดประเภทของอุปกรณ์ แต่โหมดการแสดงผลทำให้ iPhone 5 เป็นผลลัพธ์ที่ต้องการในตัวอย่างนี้


1
iPhone 5 จะรายงานขนาดหน้าจอปกติ 480x320 โดยไม่มีภาพเริ่มต้นใหม่ สำหรับฉันนี่เป็นพฤติกรรมที่ต้องการ
hfossli

3
อาจมีประโยชน์เพิ่มเติม#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)ซึ่งจะช่วยกำหนดความแตกต่างระหว่างทั้ง iPhone4 และ iPhone5 และ iPad Retina และไม่ใช่เรตินา
bshirley

1
ฉันไม่เห็นด้วย. ฉันคิดว่าคำศัพท์ 'ไวด์สกรีน' ควรจะหมดไปเนื่องจากมันล้าสมัยอย่างรวดเร็ว
hfossli

1
@Dvole นั่นเป็นวิธีที่ iOS 8 ทำงาน ใช้SCREEN_MAX_LENGTHเพื่อรับ 568 ในการหมุนทั้งหมดบน iPhone 5
hfossli

1
@MattParkins ฉันจะแนะนำให้ใช้มีประสิทธิภาพมากขึ้นการตรวจสอบรูปแบบstackoverflow.com/questions/13366976/...
hfossli

69

ทางออกที่ง่ายจริงๆ

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

1
ฮ่าฮ่าสั้นและง่ายทำแบบเดียวกัน :) เดินขบวนเพื่อรักษาค่าใช้จ่ายต่ำ! การวางสิ่งต่าง ๆ ในมาโครไม่ใช่เรื่องที่ท้าทาย ...
benjamin.ludwig

2
ดีไม่วางสิ่งที่อยู่ในฟังก์ชั่นแมโครหรือมีแนวโน้มที่จะไม่แห้ง ... จากช่วงเวลาที่คุณต้องทำเครื่องหมายนี้มากกว่าหนึ่งครั้ง ...
hfossli

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

ขอบคุณคุณช่วยชีวิตฉันไว้: D แต่ฉันไม่รู้ว่าทำไมมาโคร: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] ขอบเขต] .size.height == 568.0) ==> ไม่ทำงานในโปรแกรมจำลอง iOS 7.1 ก่อน ฉันยังคงทำงานกับ XCode 4.6 อยู่ OMG iOS 7.1 และ Xcode 5
Linh Nguyen

อัปเดตคำตอบด้านล่างเพื่อรองรับขนาดหน้าจอ iPhone 6 และ 6 บวก
Sam B

28

ตอนนี้เราต้องพิจารณาขนาดหน้าจอ iPhone 6 และ 6Plus นี่คือคำตอบที่อัพเดทแล้ว

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    //its iPhone. Find out which one?

    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    else if(result.height == 568)
    {
        // iPhone 5
    }
    else if(result.height == 667)
    {
        // iPhone 6
    }
   else if(result.height == 736)
    {
        // iPhone 6 Plus
    }
}
else
{
     //its iPad
}

ข้อมูลที่เป็นประโยชน์บางอย่าง

iPhone 6 Plus   736x414 points  2208x1242 pixels    3x scale    1920x1080 physical pixels   401 physical ppi    5.5"
iPhone 6        667x375 points  1334x750 pixels     2x scale    1334x750 physical pixels    326 physical ppi    4.7"
iPhone 5        568x320 points  1136x640 pixels     2x scale    1136x640 physical pixels    326 physical ppi    4.0"
iPhone 4        480x320 points  960x640 pixels      2x scale    960x640 physical pixels     326 physical ppi    3.5"
iPhone 3GS      480x320 points  480x320 pixels      1x scale    480x320 physical pixels     163 physical ppi    3.5"

มันใช้งานไม่ได้สำหรับฉัน iPhone 5 ตัดสินใจเป็น 4 iPhone 6+ ไม่ได้ตัดสินใจเลยโอ้ฉันเข้าใจแล้วฉันอยู่ในแนวนอนฉันควรเปลี่ยนความสูงด้วยความกว้าง :)
ColdSteel

หากแอปของคุณอยู่ในโหมดแนวนอนให้แน่ใจว่าคุณเปลี่ยนผลลัพธ์ความสูงเป็นผลให้แบนด์วิดท์
Sam B

อืม .. บน iPhone 4 (iOS 6.0) มันไม่ได้สลับ :( อาจเป็น iOS 6.0 prob หรือ iPhone 4 ได้ไหม
ColdSteel

โอเคฉันตรวจสอบมุมมองที่สลับเฉพาะใน iOS 8 ขึ้นไป
ColdSteel

iPhone 6 ให้ความสูง = 568
MaxEcho

15

ฉันมีอิสระที่จะใส่แมโครโดย Macmade ลงในฟังก์ชัน C และตั้งชื่ออย่างถูกต้องเพราะตรวจพบความพร้อมใช้งานของจอกว้างและไม่จำเป็นต้องเป็น iPhone 5

แมโครยังไม่ได้ตรวจสอบการทำงานบน iPhone 5 ในกรณีที่โครงการไม่รวมDefault-568h@2x.png หากไม่มีภาพเริ่มต้นใหม่ iPhone 5 จะรายงานขนาดหน้าจอปกติ 480x320 (เป็นคะแนน) ดังนั้นการตรวจสอบไม่ได้มีไว้สำหรับความพร้อมใช้งานไวด์สกรีนเท่านั้น แต่สำหรับการเปิดใช้งานโหมดไวด์สกรีนเช่นกัน

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}

ฉันยังคงชอบแมโครเพราะเหตุผลด้านประสิทธิภาพ โปรดดูการแก้ไขคำตอบของฉัน นอกจากนี้ยังตรวจสอบรูปแบบ
Macmade

1
คุณกำลังพูดว่า iPhone 5 จะรายงานขนาดหน้าจอปกติ 480x320 โดยไม่มีภาพเริ่มต้นใหม่ แต่ฉันคิดว่าไม่มีจุดตรวจจับ iPhone 5 ในแอพที่ไม่ได้รับการปรับปรุง :)
Macmade

@Macmade แน่นอนไม่มีประเด็น แต่ควรจำไว้ในกรณีที่การตรวจจับใช้งานไม่ได้ นอกจากนี้ฟังก์ชั่นสามารถinlined พวกเขาจะได้รับการ inline ที่เครื่องมือเพิ่มประสิทธิภาพของคอมไพเลอร์คิดว่ามันเป็นความคิดที่ดีและที่ที่สามารถรู้ว่ามันอนุญาต (เช่นฟังก์ชั่นอยู่ในโมดูลเดียวกัน) การนำบางสิ่งมาใช้เช่นนี้ผ่านฟังก์ชั่นอาจทำให้การตรวจสอบประเภทเพิ่มเติม
Ivan Vučica

4
คำถามที่เกี่ยวข้องกับประสิทธิภาพคือทำไมคุณต้องเรียกใช้การตรวจสอบนี้หลายพันครั้งระหว่างลูปการเรนเดอร์ของคุณ มิฉะนั้นประสิทธิภาพจะไม่เป็นประเด็นและมีความชัดเจนและหลีกเลี่ยงผลข้างเคียงที่มีความสำคัญมากกว่า
LearnCocos2D

ฉันให้ +1 กับคุณเพราะฉันชอบฟังก์ชั่นแยกต่างหากมากกว่ามาโคร แต่ฉันต้องชี้ให้เห็นว่ามันไม่ถูกต้องหรือสมบูรณ์ ในการตรวจจับไวด์สกรีนอย่าดูที่ความสูงของหน้าจอ ให้ดูที่อัตราส่วนภาพและส่งกลับค่าจริงหากอัตราส่วนกว้างกว่าหรือเท่ากับ 16: 9
ทอดด์เลห์แมน

11

นี่คือรหัสของเราทดสอบผ่าน ios7 / ios8 สำหรับ iphone4, iphone5, ipad, iphone6, iphone6p ไม่ว่าบนอุปกรณ์หรือเครื่องจำลอง:

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and       iPod touch style UI

#define IS_IPHONE_5_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0f)

#define IS_IPHONE_5_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 568.0f)
#define IS_IPHONE_6_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f)
#define IS_IPHONE_6P_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) < 568.0f)

#define IS_IPHONE_5 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_5_IOS8 : IS_IPHONE_5_IOS7 )
#define IS_IPHONE_6 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6_IOS8 : IS_IPHONE_6_IOS7 )
#define IS_IPHONE_6P ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6P_IOS8 : IS_IPHONE_6P_IOS7 )
#define IS_IPHONE_4_AND_OLDER ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_4_AND_OLDER_IOS8 : IS_IPHONE_4_AND_OLDER_IOS7 )

ฉันกำลังทดสอบ iPhone 6P และหากคำสั่งของฉันอยู่ในสภาพ IS_IPHONE_5 สิ่งนี้จะเป็นไปได้อย่างไรรหัสของคุณดูดีหรือไม่? ฉันทำสำเนาตรงและวางแบบง่ายๆถ้า / อย่างอื่นและฉันรู้ว่าโทรศัพท์ของฉันคือ iOS 6 บวกกับการใช้งาน iOS 8.3
Whyoz

7

ฉันใช้คำตอบของ hfossli และแปลเป็น Swift

let IS_IPAD = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let IS_IPHONE = UIDevice.currentDevice().userInterfaceIdiom == .Phone
let IS_RETINA = UIScreen.mainScreen().scale >= 2.0

let SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
let SCREEN_MAX_LENGTH = max(SCREEN_WIDTH, SCREEN_HEIGHT)
let SCREEN_MIN_LENGTH = min(SCREEN_WIDTH, SCREEN_HEIGHT)

let IS_IPHONE_4_OR_LESS = (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
let IS_IPHONE_5 = (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
let IS_IPHONE_6 = (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
let IS_IPHONE_6P = (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

6

นี่คือแมโครสำหรับโครงการ cocos2d ของฉัน ควรเหมือนกันสำหรับแอปอื่น ๆ

#define WIDTH_IPAD 1024
#define WIDTH_IPHONE_5 568
#define WIDTH_IPHONE_4 480
#define HEIGHT_IPAD 768
#define HEIGHT_IPHONE 320

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

//width is height!
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_5 )
#define IS_IPHONE_4 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_4 )

#define cp_ph4(__X__, __Y__) ccp(cx_ph4(__X__), cy_ph4(__Y__))
#define cx_ph4(__X__) (IS_IPAD ? (__X__ * WIDTH_IPAD / WIDTH_IPHONE_4) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPHONE_4) : (__X__)))
#define cy_ph4(__Y__) (IS_IPAD ? (__Y__ * HEIGHT_IPAD / HEIGHT_IPHONE) : (__Y__))

#define cp_pad(__X__, __Y__) ccp(cx_pad(__X__), cy_pad(__Y__))
#define cx_pad(__X__) (IS_IPAD ? (__X__) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPAD) : (__X__ * WIDTH_IPHONE_4 / WIDTH_IPAD)))
#define cy_pad(__Y__) (IS_IPAD ? (__Y__) : (__Y__ * HEIGHT_IPHONE / HEIGHT_IPAD))


3

ใน Swift โปรเจค iOS 8+ ที่ฉันชอบทำเพิ่มขึ้นUIScreenเช่น:

extension UIScreen {

    var isPhone4: Bool {
        return self.nativeBounds.size.height == 960;
    }

    var isPhone5: Bool {
        return self.nativeBounds.size.height == 1136;
    }

    var isPhone6: Bool {
        return self.nativeBounds.size.height == 1334;
    }

    var isPhone6Plus: Bool {
        return self.nativeBounds.size.height == 2208;
    }

}

(หมายเหตุ: nativeBoundsเป็นพิกเซล)

แล้วรหัสจะเป็นดังนี้:

if UIScreen.mainScreen().isPhone4 {
    // do smth on the smallest screen
}

ดังนั้นรหัสทำให้ชัดเจนว่านี่คือการตรวจสอบหน้าจอหลักไม่ใช่สำหรับรุ่นอุปกรณ์


2

การยืมจากคำตอบของ Samrat Mazumdar นี่เป็นวิธีสั้น ๆ ที่ประมาณขนาดหน้าจอของอุปกรณ์ มันใช้งานได้กับอุปกรณ์ล่าสุด แต่อาจล้มเหลวในอนาคต (เป็นวิธีการคาดเดาทั้งหมด) นอกจากนี้ยังจะสับสนถ้าอุปกรณ์ถูกมิเรอร์ (ส่งคืนขนาดหน้าจอของอุปกรณ์ไม่ใช่ขนาดหน้าจอมิเรอร์)

#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7

+ (CGFloat)screenPhysicalSize
{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if (result.height < 500)
            return SCREEN_SIZE_IPHONE_CLASSIC;  // iPhone 4S / 4th Gen iPod Touch or earlier
        else
            return SCREEN_SIZE_IPHONE_TALL;  // iPhone 5
    }
    else
    {
        return SCREEN_SIZE_IPAD_CLASSIC; // iPad
    }
} 

จำเป็นต้องมีการแก้ไขสำหรับ iPad mini ซึ่งฉันไม่เชื่อว่าคุณจะสามารถกำหนดได้ในคฤหาสน์นี้
Daniel

ใช่ iPad mini มีความละเอียดเช่นเดียวกับ iPad2 ดังนั้นวิธีนี้จึงใช้ไม่ได้ ไม่แน่ใจว่าจะจัดการกับกรณีที่ตอนนี้ ...
เจฟฟ์เฮย์

1
คุณไม่ควรที่จะ คุณสามารถตรวจสอบตัวระบุอุปกรณ์สำหรับซื้อ "iPad 2,5" และคุณต้องตรวจสอบ 2,6 และ 2,7 - รุ่น wifi เท่านั้น gsm และ CDMA แต่นั่นหมายความว่ามินิ iPad ถัดไปจะวางจำหน่ายและคุณจะต้องอัปเดตเป็นรหัสยากสำหรับตัวระบุเหล่านั้นด้วยซึ่งคุณไม่สามารถรู้ล่วงหน้าได้ คุณไม่สามารถรู้ได้อย่างต่อเนื่องเมื่อคุณอยู่ในมินิ iPad เพราะจริง ๆ แล้วคุณไม่ควรลอง "ปรับ" สำหรับหน้าจอที่เล็กกว่า
Daniel

2

ฉันคิดว่ามันจะดีถ้าแมโครนี้จะทำงานในอุปกรณ์และเครื่องมือจำลองด้านล่างเป็นวิธีแก้ปัญหา

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"]) || ([[[UIDevice currentDevice] model] isEqualToString: @"iPhone Simulator"]))
#define IS_IPOD   ([[[UIDevice currentDevice]model] isEqualToString:@"iPod touch"])
#define IS_IPHONE_5 ((IS_IPHONE || IS_IPOD) && IS_WIDESCREEN)

2

ฉันพบว่าคำตอบไม่รวมกรณีพิเศษสำหรับ Simulators

#define IS_WIDESCREEN ( [ [ UIScreen mainScreen ] bounds ].size.height == 568  )
#define IS_IPHONE ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPhone"].location != NSNotFound)
#define IS_IPAD ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPad"].location != NSNotFound)
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

2
+(BOOL)isDeviceiPhone5
{
    BOOL iPhone5 = FALSE;

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568)
    {
        // code for 4-inch screen
        iPhone5 = TRUE;
    }
    else
    {
        iPhone5 = FALSE;
        // code for 3.5-inch screen
    }
    return iPhone5;

}

iPhone5 = FALSE;ไม่จำเป็นเนื่องจากตัวแปรมีค่านั้นแล้วหากไม่มีการเปลี่ยนแปลง
mcont

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

NSLog(@"screen soze is %f",height);

  if (height>550) {

          // 4" screen-do some thing
     }

  else if (height<500) {

        // 3.5 " screen- do some thing

     }

1

การใช้ขนาดผิดในหลาย ๆ ระดับ เราจะถามระบบอย่างไร

- (NSString *) getDeviceModel
{
    struct utsname systemInfo;
    uname(&systemInfo);
    return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}

ถ่ายจากวิธีที่ดีที่สุดในการตรวจจับประเภทฮาร์ดแวร์ iPhone4 หรือ iPhone5? , edzio27 คำตอบ


1

วิธีนี้คุณสามารถตรวจหาตระกูลอุปกรณ์

    #import <sys/utsname.h>
    NSString* deviceName()
    {
        struct utsname systemInformation;
        uname(&systemInformation);
        NSString *result = [NSString stringWithCString:systemInformation.machine
                                              encoding:NSUTF8StringEncoding];
        return result;
    }

    #define isIPhone5  [deviceName() rangeOfString:@"iPhone5,"].location != NSNotFound
    #define isIPhone5S [deviceName() rangeOfString:@"iPhone6,"].location != NSNotFound

1

หากโครงการถูกสร้างขึ้นโดยใช้ Xcode 6 ให้ใช้รหัสที่กล่าวถึงด้านล่างเพื่อตรวจจับอุปกรณ์ ..

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136){
            printf("Device Type : iPhone 5,5S/iPod 5 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1334){
            printf("Device Type : iPhone 6 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 2208){
            printf("Device Type : iPhone 6+ ");

        }
    }
}else{
    printf("Device Type : iPad");
}

หากโครงการถูกสร้างขึ้นใน Xcode 5 และเปิดใน Xcode 6 จากนั้นใช้รหัสที่กล่าวถึงด้านล่างเพื่อตรวจสอบอุปกรณ์ (รหัสนี้ใช้งานได้หากไม่มีการกำหนดภาพเปิดตัวสำหรับ iPhone 6,6+)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
       if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s");
            appType=1;
        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136 || [[UIScreen mainScreen] nativeBounds].size.height == 1704){
            printf("Device Type : iPhone 5,5S,6,6S/iPod 5 ");
            appType=3;
        }
    }
}else{
    printf("Device Type : iPad");
    appType=2;
}

หากคุณยังคงใช้ Xcode 5 อยู่ด้วยกันให้ใช้รหัสต่อไปนี้เพื่อตรวจจับอุปกรณ์ (iPhone 6 และ 6+ จะไม่ถูกตรวจจับ)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] bounds].size.width,(int)[[UIScreen mainScreen] bounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
        if(result.height == 960 || result.height == 480){
            printf("Device Type : iPhone 4,4S ");

        }else if(result.height == 1136){
            printf("Device Type : iPhone 5s/iPod 5");

        }
    }
}else{
    printf("Device Type : iPad");

}

1
  1. เพิ่ม 'New Swift File' -> AppDelegateEx.swift

  2. เพิ่มส่วนขยายไป AppDelegate

    import UIKit
    extension AppDelegate {
         class func isIPhone5 () -> Bool{
             return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 568.0
        }
        class func isIPhone6 () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 667.0
        }
        class func isIPhone6Plus () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 736.0
        }  
    }
  3. การใช้งาน:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }

1

ใน Swift 3 คุณสามารถใช้ KRDeviceType ในระดับง่าย ๆ ของฉัน

https://github.com/ulian-onua/KRDeviceType

มันบันทึกไว้อย่างดีและรองรับผู้ประกอบการ ==,> =, <=

ตัวอย่างเช่นเพื่อตรวจสอบว่าอุปกรณ์มีขอบเขต iPhone 6 / 6s / 7 หรือไม่คุณสามารถใช้การเปรียบเทียบต่อไปได้:

if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}

ในการตรวจสอบว่าอุปกรณ์มีขอบเขตของ iPhone 5 / 5S / SE หรือก่อนหน้า (iPhone 4s) คุณสามารถใช้การเปรียบเทียบต่อไป:

if KRDeviceType() <= .iPhone5 {   //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}

1

คำตอบนี้ได้รับการตอบร้อยครั้ง แต่วิธีนี้ใช้ได้ผลดีที่สุดสำหรับฉันและช่วยแก้ไขปัญหาเมื่อมีการเปิดตัวอุปกรณ์ใหม่และฉันไม่ได้กำหนดขนาด

Swift 5 Helper:

extension UIScreen {
    func phoneSizeInInches() -> CGFloat {
        switch (self.nativeBounds.size.height) {
        case 960, 480:
            return 3.5  //iPhone 4
        case 1136:
            return 4    //iPhone 5
        case 1334:
            return 4.7  //iPhone 6
        case 2208:
            return 5.5  //iPhone 6 Plus
        case 2436:
            return 5.8  //iPhone X
        case 1792:
            return 5.5  //iPhone XR
        case 2688:
            return 6.5  //iPhone XS Max
        default:
            let scale = self.scale
            let ppi = scale * 163
            let width = self.bounds.size.width * scale
            let height = self.bounds.size.height * scale
            let horizontal = width / ppi, vertical = height / ppi
            let diagonal = sqrt(pow(horizontal, 2) + pow(vertical, 2))
            return diagonal
        }
    }
}

นี่เป็นเพราะง่ายต่อการจดจำขนาดนิ้วของโทรศัพท์เช่นอุปกรณ์ "5.5 นิ้ว" หรือ "4.7 นิ้ว" แต่ยากที่จะจำขนาดพิกเซลที่แน่นอน

if UIScreen.main.phoneSizeInInches() == 4 {
  //do something with only 4 inch iPhones
}

สิ่งนี้ยังให้โอกาสคุณทำสิ่งนี้:

if UIScreen.main.phoneSizeInInches() < 5.5 {
  //do something all iPhones smaller than the plus
}

ค่าเริ่มต้น:พยายามที่จะใช้ขนาดหน้าจอและขนาดที่จะลองและคำนวณนิ้วในแนวทแยง นี่เป็นกรณีที่ขนาดอุปกรณ์ใหม่ปรากฏขึ้นมันจะพยายามอย่างดีที่สุดในการระบุและรหัสเช่นตัวอย่างสุดท้ายยังคงใช้งานได้


0

ใช้รหัสต่อไปนี้:

CGFloat screenScale = [[UIScreen mainScreen] scale];

CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale); 

if (screenSize.height==1136.000000)
{ 
    // Here iPhone 5 View

    // Eg: Nextview~iPhone5.Xib
} else {
   // Previous Phones 

   // Eg : Nextview.xib
}

0

นี่คือการทดสอบที่ถูกต้องของอุปกรณ์โดยไม่ขึ้นอยู่กับทิศทาง

- (BOOL)isIPhone5
{
    CGSize size = [[UIScreen mainScreen] bounds].size;
    if (MIN(size.width,size.height) == 320 && MAX(size.width,size.height == 568)) {
        return YES;
    }
    return NO;
}

-2

ใช้ในการตรวจจับอุปกรณ์ iPhone และ iPad ทุกรุ่น

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 

iPhone 6 ไม่มีจอแสดงผลเรตินา?
vikingosegundo

iPhone6 ​​มีจอแสดงผล ratina (@ 2X) และ iPhone6 ​​plus มีหน้าจอ HD (@ 3X)
Vaibhav Sharma

ดังนั้นถ้าทดสอบIS_RETINAกับ iPhone 6 plus จะมีการเรียกใช้รหัส 1x หรือไม่
vikingosegundo


1
คุณไม่ได้รับมันกฎของคุณจะให้ผลผลิตที่มันควรผลผลิต@1x @3xอย่างไรก็ตาม: ตามที่คุณคัดลอกและวาง: -1
vikingosegundo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.