Làm cách nào để phát hiện iPhone 5 (thiết bị màn hình rộng)?


300

Tôi vừa nâng cấp lên XCode 4.5 GM và phát hiện ra rằng bây giờ bạn có thể áp dụng kích thước '4 "Retina' cho bộ điều khiển chế độ xem của mình trong bảng phân cảnh.

Bây giờ nếu tôi muốn tạo một ứng dụng chạy trên cả iPhone 4 và 5, tất nhiên tôi phải xây dựng mọi cửa sổ hai lần, nhưng tôi cũng phải phát hiện xem người dùng có iPhone với màn hình 3,5 "hay 4" hay không lượt xem.

Làm thế nào tôi nên làm điều đó?


2
Bạn không phải xây dựng mỗi "cửa sổ" hai lần. Chỉ những người được cho là phù hợp chính xác với kích thước màn hình sẽ phải được chuyển tiếp. Giải pháp có vẻ khá rõ ràng, chỉ cần kiểm tra kích thước cửa sổ và thêm quyết định trường hợp dựa trên kích thước được trả về.
Đến

1
Chà, về cơ bản là đúng, nhưng tôi muốn sử dụng kích thước màn hình phụ theo một cách hoàn toàn khác, giống như bạn có thể làm với màn hình ngang.
Finn Gaida


Câu hỏi này có nên được cập nhật theo các thiết bị mới không? Ví dụ: "Cách phát hiện thiết bị iOS theo kích thước màn hình"?
hfossli

Câu trả lời:


467

Trước hết, bạn không nên xây dựng lại tất cả các chế độ xem của mình để phù hợp với màn hình mới, cũng như không sử dụng các chế độ xem khác nhau cho các kích thước màn hình khác nhau.

Sử dụng khả năng tự động thay đổi kích thước của iOS, để chế độ xem của bạn có thể điều chỉnh và điều chỉnh bất kỳ kích thước màn hình nào.

Điều đó không khó lắm, hãy đọc một số tài liệu về điều đó. Nó sẽ giúp bạn tiết kiệm rất nhiều thời gian.

iOS 6 cũng cung cấp các tính năng mới về điều này.
Hãy chắc chắn đọc thay đổi API iOS 6 trên trang web Nhà phát triển của Apple.
Và kiểm tra các khả năng AutoLayout mới của iOS 6 .

Điều đó nói rằng, nếu bạn thực sự cần phát hiện iPhone 5, bạn chỉ cần dựa vào kích thước màn hình .

[ [ UIScreen mainScreen ] bounds ].size.height

Màn hình của iPhone 5 có chiều cao 568.
Bạn có thể tưởng tượng một macro, để đơn giản hóa tất cả những điều này:

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

Việc sử dụng fabsvới epsilon có ở đây để ngăn ngừa các lỗi chính xác, khi so sánh các điểm nổi, như được nêu trong các nhận xét của H2CO3.

Vì vậy, từ bây giờ bạn có thể sử dụng nó trong các câu lệnh if / other:

if( IS_IPHONE_5 )
{}
else
{}

Chỉnh sửa - Phát hiện tốt hơn

Như một số người đã nêu, điều này chỉ phát hiện màn hình rộng chứ không phải iPhone 5 thực tế.

Các phiên bản tiếp theo của iPod touch cũng có thể có màn hình như vậy, vì vậy chúng tôi có thể sử dụng một bộ macro khác.

Hãy đổi tên macro ban đầu IS_WIDESCREEN:

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

Và hãy thêm các macro phát hiện mô hình:

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

Bằng cách này, chúng tôi có thể đảm bảo chúng tôi có một mẫu iPhone màn hình rộng và chúng tôi có thể xác định lại IS_IPHONE_5macro:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Cũng lưu ý rằng, như @ LearnCocos2D đã nêu, các macro này sẽ không hoạt động nếu ứng dụng không được tối ưu hóa cho màn hình iPhone 5 (thiếu hình ảnh Mặc định-568h@2x.png), vì kích thước màn hình vẫn sẽ là 320x480 một trường hợp.

Tôi không nghĩ đây có thể là một vấn đề, vì tôi không hiểu tại sao chúng tôi muốn phát hiện iPhone 5 trong một ứng dụng không được tối ưu hóa.

QUAN TRỌNG - Hỗ trợ iOS 8

Trên iOS 8, thuộc boundstính của UIScreenlớp hiện phản ánh định hướng thiết bị .
Vì vậy, rõ ràng, mã trước đó sẽ không hoạt động.

Để khắc phục điều này, bạn chỉ cần sử dụng thuộc tính mới nativeBounds, thay vì bounds, nó sẽ không thay đổi theo hướng và vì nó dựa trên chế độ dọc.
Lưu ý rằng kích thước của nativeBoundsđược đo bằng pixel, vì vậy đối với iPhone 5, chiều cao sẽ là 1136 thay vì 568.

Nếu bạn cũng đang nhắm mục tiêu iOS 7 trở xuống, hãy chắc chắn sử dụng tính năng phát hiện tính năng, vì việc gọi nativeBoundstrước iOS 8 sẽ làm hỏng ứng dụng của bạn:

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

Bạn có thể điều chỉnh các macro trước theo cách sau:

#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 )

Và rõ ràng, nếu bạn cần phát hiện iPhone 6 hoặc 6 Plus, hãy sử dụng các kích thước màn hình tương ứng.


7
Điều này là sai, bạn sẽ phải sử dụng#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3: Lưu ý rằng việc so sánh DBL_EPSILONlà không cần thiết ở đây và việc ==so sánh sẽ không thất bại: chỉ cần thực hiện so sánh bằng cách sử dụng khác biệt nếu giá trị dấu phẩy động không thể được biểu thị bằng một con số chính xác ( 1.0/3.0*3.0ví dụ như). Đọc bài viết này để biết thêm;)
AliSoftware

2
Câu trả lời này không đúng. Tại sao nó nhận được rất nhiều ngón tay cái lên? bạn không thể chỉ sử dụng chiều cao để xác định xem đó có phải là màn hình rộng hay không. anh bạn ...
OMGPOP

5
Tôi có thể thêm: Nếu bạn muốn nó hoạt động với trình giả lập, hãy sử dụng mô hình này: #define IS_IPHONE (mô hình ([[[[UIDevice currentDevice]] isEqualToString: @ "iPhone"]) | @ "Trình mô phỏng iPhone"]))
david

31
Câu trả lời này là sự điên rồ. Công cụ này về việc khuyến nghị không so sánh các loại phao đặc biệt này (trong thực tế là - và nếu bạn biết Apple nên biết rằng sẽ luôn luôn là - số nguyên) với == là vô nghĩa và quá phức tạp. Ngoài ra, tôi nghĩ tốt hơn nên sử dụng UI_USER_INTERFACE_IDIOM () để phát hiện iPhone vì nó hoạt động tốt cả trên thiết bị và trình giả lập (và nó có thể nhanh hơn phương pháp UIDevice). Điều này chỉ hoạt động tốt và là cách đơn giản hơn để đọc: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez

232

Đã thử nghiệm và được thiết kế cho mọi kết hợp SDK và HĐH:

Nhanh

Đã thêm các loại iPad. iPad 2 và iPad mini là những chiếc iPad không có võng mạc. Trong khi iPad Mini 2 trở lên, iPad 3, 4, iPad Air, Air 2, Air 3 và iPad Pro 9.7 có cùng độ phân giải logic là 1024. iPad Pro có độ dài tối đa là 1366. Tham khảo

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

Xem nó trong hành động https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Lưu ý: Nếu ví dụ iPhone 6 ở chế độ phóng to, UI là phiên bản phóng to của iPhone 5. Các chức năng này không xác định loại thiết bị, nhưng chế độ hiển thị do đó iPhone 5 là kết quả mong muốn trong ví dụ này.

Mục tiêu-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)

Cách sử dụng: http://pastie.org/9687735

Lưu ý: Nếu ví dụ iPhone 6 ở chế độ phóng to, UI là phiên bản phóng to của iPhone 5. Các chức năng này không xác định loại thiết bị, nhưng chế độ hiển thị do đó iPhone 5 là kết quả mong muốn trong ví dụ này.


1
iPhone 5 sẽ báo cáo kích thước màn hình 480x320 thông thường, không có hình ảnh mặc định mới. Đối với tôi đây là hành vi mong muốn.
hfossli

3
Một bổ sung có thể hữu ích là #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)sẽ giúp xác định sự khác biệt giữa cả iPhone4 và iPhone5 và iPad Retina và không võng mạc
bshirley

1
Tôi không đồng ý. Tôi nghĩ rằng thuật ngữ 'màn hình rộng' nên bị bỏ qua vì nó nhanh chóng lỗi thời.
hfossli

1
@Dvole đó là cách iOS 8 hoạt động. Sử dụng SCREEN_MAX_LENGTHđể nhận 568 trong tất cả các lần quay trên iPhone 5.
hfossli

1
@MattParkins Tôi sẽ đề nghị sử dụng mô hình mạnh hơn kiểm tra stackoverflow.com/questions/13366976/ .
hfossli

69

Giải pháp thực sự đơn giản

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
haha ngắn và simpel, đã làm như vậy :) nhảy lên vì giữ quá thấp! đưa công cụ vào một macro không phải là một thách thức ...
benjamin.ludwig

2
Cũng không đặt mọi thứ vào macro hoặc các chức năng có xu hướng không bị KHÔ ... Từ lúc này, bạn cần thực hiện kiểm tra này nhiều lần ...
hfossli

Yup, nhưng xác định macro như được hiển thị ở trên, sẽ thuận tiện và dễ dàng hơn, bạn không cần phải dán ghi này nếu ... mọi lúc.
Resty

Cảm ơn, Bạn đã cứu mạng tôi: D, Nhưng tôi không biết tại sao Macro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] giới hạn] .size.height == 568.0) ==> Không hoạt động trong trình giả lập iOS 7.1, trước đó mà tôi vẫn làm việc trên XCode 4.6. OMG iOS 7.1 & Xcode 5
Linh Nguyễn

cập nhật câu trả lời bên dưới vào tài khoản cho kích thước màn hình iPhone 6 và 6 plus
Sam B

28

Bây giờ chúng ta cần tính đến kích thước màn hình iPhone 6 và 6Plus. Đây là một câu trả lời cập nhật

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
}

Một số thông tin hữu ích

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"

Nó chỉ không hoạt động với tôi iPhone 5 đã quyết định vì 4 iPhone 6+ không quyết định gì cả Oh Tôi hiểu rồi Tôi nên thay đổi chiều cao theo chiều rộng :)
ColdSteel

nếu ứng dụng của bạn ở chế độ ngang thì hãy đảm bảo bạn thay đổi kết quả. chuyển sang kết quả. Băng thông
Sam B

hmm .. trên iPhone 4 (iOS 6.0), nó không trao đổi :( có thể là bản thử nghiệm iOS 6.0 hoặc iPhone 4?
ColdSteel

Được rồi, tôi đã kiểm tra chế độ xem chỉ hoán đổi trong iOS 8 trở lên
ColdSteel

iPhone 6 cho chiều cao = 568
MaxEcho

15

Tôi đã có quyền tự do đưa macro của MacADE vào chức năng C và đặt tên cho nó đúng vì nó phát hiện tính khả dụng của màn hình rộngKHÔNG nhất thiết phải là iPhone 5.

Macro cũng không phát hiện chạy trên iPhone 5 trong trường hợp dự án không bao gồm Mặc định-568h@2x.png . Nếu không có hình ảnh Mặc định mới, iPhone 5 sẽ báo cáo kích thước màn hình 480x320 thông thường (tính theo điểm). Vì vậy, kiểm tra không chỉ dành cho màn hình rộng mà còn cho phép chế độ màn hình rộng .

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

Tôi vẫn thích các macro, vì lý do hiệu suất. Xin vui lòng xem chỉnh sửa để trả lời của tôi. Nó cũng kiểm tra mô hình.
Maccraft

1
Bạn cũng đúng khi nói iPhone 5 sẽ báo cáo kích thước màn hình 480x320 thông thường, không có hình ảnh mặc định mới. Nhưng tôi nghĩ không có điểm nào phát hiện iPhone 5 trong một ứng dụng không được tối ưu hóa. :)
Maccraft

@MacADE Thật vậy, không có điểm nào, nhưng thật tốt khi ghi nhớ trong trường hợp phát hiện trường hợp không hoạt động. Ngoài ra, các chức năng có thể được inlined. Chúng cũng sẽ được nội tuyến trong đó trình tối ưu hóa của trình biên dịch nghĩ rằng đó là một ý tưởng hay và nơi nó có thể biết nó được cho phép (ví dụ: chức năng nằm trong cùng một mô-đun). Việc thực hiện những thứ như thế này thông qua một chức năng đôi khi có thể mang lại kiểm tra loại bổ sung.
Ivan Vučica

4
Câu hỏi liên quan đến hiệu suất là, tại sao bạn sẽ chạy kiểm tra này hàng ngàn lần trong vòng lặp kết xuất của bạn? Mặt khác, hiệu suất là một vấn đề không rõ ràng và rõ ràng và tránh tác dụng phụ có tầm quan trọng lớn hơn.
LearnCocos2D

Tôi đã cho bạn +1 cho điều này vì tôi thích chức năng riêng biệt hơn là macro, nhưng tôi phải chỉ ra rằng nó không thực sự chính xác hoặc hoàn chỉnh. Để phát hiện màn hình rộng, đừng nhìn vào chiều cao của màn hình. Thay vào đó, hãy nhìn vào tỷ lệ khung hình và chỉ trả về true nếu tỷ lệ khung hình lớn hơn hoặc bằng 16: 9.
Todd Lehman

11

Đây là mã của chúng tôi, thử nghiệm được chuyển trên ios7 / ios8 cho iphone4, iphone5, ipad, iphone6, iphone6p, không có vấn đề gì trên thiết bị hoặc trình giả lập:

#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 )

Tôi đang thử nghiệm trên iPhone 6P và câu lệnh if của tôi có rơi vào điều kiện IS_IPHONE_5 không? Làm thế nào điều này có thể, mã của bạn trông tốt? Tôi đã thực hiện một bản sao thẳng và dán bằng một cái đơn giản nếu / khác và tôi biết điện thoại của tôi là 6 cộng với chạy iOS 8.3.
whyoz

7

Tôi đã sử dụng câu trả lời của hfossli và dịch nó sang 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

đây là macro cho dự án cocos2d của tôi. nên giống nhau cho các ứng dụng khác.

#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))

5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}

3

Trong Swift, dự án iOS 8+ tôi muốn thực hiện một tiện ích mở rộng UIScreen, như:

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

}

(GHI CHÚ: nativeBounds bằng pixel).

Và sau đó mã sẽ như sau:

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

Vì vậy, mã làm cho nó rõ ràng rằng đây là một kiểm tra cho màn hình chính, không phải cho mô hình thiết bị.


2

Mượn từ câu trả lời của Samrat Mazumdar, đây là một phương pháp ngắn để ước tính kích thước màn hình thiết bị. Nó hoạt động với các thiết bị mới nhất, nhưng có thể thất bại trên các thiết bị trong tương lai (vì tất cả các phương pháp đoán có thể). Nó cũng sẽ bị lẫn lộn nếu thiết bị được nhân đôi (trả về kích thước màn hình của thiết bị, không phải kích thước màn hình được nhân đôi)

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

Cần sửa đổi cho iPad mini, tôi không tin rằng bạn sẽ có thể xác định trong trang viên này.
Daniel

Vâng, iPad mini có độ phân giải tương tự iPad2, vì vậy phương pháp này không hiệu quả với điều đó. Không chắc chắn cách xử lý trường hợp đó ngay bây giờ ...
Jeff Hay

1
Bạn không nên. Bạn có thể kiểm tra số nhận dạng thiết bị để mua "iPad 2,5", bạn cũng cần kiểm tra 2,6 và 2,7 - phiên bản chỉ wifi, GSM và CDMA. Nhưng điều đó có nghĩa là iPad mini tiếp theo sẽ được phát hành và bạn sẽ cần cập nhật mã cứng lên những số nhận dạng mà bạn không thể biết trước. Bạn không thể liên tục biết khi nào bạn sử dụng iPad mini vì thực sự bạn không nên cố gắng "tối ưu hóa" cho màn hình nhỏ hơn
Daniel

2

Tôi nghĩ sẽ tốt nếu macro này hoạt động trong thiết bị và trình giả lập, dưới đây là giải pháp.

#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

Tôi thấy rằng câu trả lời không bao gồm trường hợp đặc biệt cho Trình mô phỏng.

#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;là không cần thiết vì biến đã có giá trị đó nếu nó không thay đổi
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

Bằng cách này bạn có thể phát hiện gia đình thiết bị.

    #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

Nếu dự án được tạo bằng Xcode 6, thì hãy sử dụng mã được đề cập bên dưới để phát hiện các thiết bị ..

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

Nếu dự án được tạo trong Xcode 5 và được mở trong Xcode 6, thì hãy sử dụng mã được đề cập bên dưới để phát hiện các thiết bị. (Mã này hoạt động nếu không có hình ảnh khởi chạy nào cho iPhone 6,6+ được chỉ định)

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

Nếu bạn vẫn đang sử dụng Xcode 5 cùng nhau thì hãy sử dụng đoạn mã sau để phát hiện thiết bị (iPhone 6 và 6+ sẽ không bị phát hiện)

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. Thêm 'Tệp Swift mới' -> AppDelegateEx.swift

  2. thêm phần mở rộng vào 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. sử dụng:

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

1

Trong Swift 3, bạn có thể sử dụng lớp KRDeviceType đơn giản của tôi.

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

Nó cũng được ghi lại và hỗ trợ các toán tử ==,> =, <=.

Ví dụ: để phát hiện xem thiết bị có giới hạn của iPhone 6 / 6s / 7 hay không, bạn chỉ có thể sử dụng so sánh tiếp theo:

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

Để phát hiện xem thiết bị có giới hạn iPhone 5 / 5S / SE hoặc cũ hơn (iPhone 4s) hay không, bạn có thể sử dụng phép so sánh tiếp theo:

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

1

Điều này đã được trả lời hàng trăm lần nhưng giải pháp này hoạt động tốt nhất với tôi và giúp giải quyết vấn đề khi các thiết bị mới được giới thiệu và tôi không có kích thước được xác định.

Trợ giúp Swift 5:

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

Điều này là do dễ dàng ghi nhớ kích thước inch của điện thoại, như thiết bị "5,5 inch" hoặc "4,7 inch" nhưng khó nhớ kích thước pixel chính xác.

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

Điều này cũng cho bạn cơ hội để làm một cái gì đó như thế này:

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

Các mặc định: cố gắng sử dụng các kích thước màn hình và quy mô để thử và tính toán inch đường chéo. Đây là trong trường hợp một số kích thước thiết bị mới xuất hiện, nó sẽ cố gắng hết sức để xác định và mã, chẳng hạn như ví dụ cuối cùng, vẫn sẽ hoạt động.


0

sử dụng mã sau đây:

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

Dưới đây là thử nghiệm chính xác của thiết bị, không phụ thuộc vào định hướng

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

Được sử dụng để phát hiện Thiết bị iPhone và iPad của tất cả các câu thơ.

#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 không có màn hình retina?
vikingosegundo

iPhone6 ​​có màn hình ratina (@ 2X). và iPhone6 ​​plus có màn hình HD (@ 3X).
Vaibhav Sharma

Vậy nếu được thử nghiệm IS_RETINAtrên iPhone 6 plus, mã 1x được thực thi?
vikingosegundo


1
bạn không hiểu nó: các quy tắc của bạn sẽ mang lại @1x, nơi nó sẽ mang lại @3x. anyway: vì bạn chỉ đơn giản là sao chép và dán: -1
vikingosegundo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.