Bagaimana cara mendeteksi iPhone 5 (perangkat layar lebar)?

300

Saya baru saja memutakhirkan ke XCode 4.5 GM dan mengetahui bahwa Anda sekarang dapat menerapkan ukuran '4 "Retina' ke pengontrol tampilan Anda di storyboard.

Sekarang jika saya ingin membuat aplikasi yang berjalan pada iPhone 4 dan 5, tentu saja saya harus membangun setiap jendela dua kali, tetapi saya juga harus mendeteksi apakah pengguna memiliki iPhone dengan layar 3,5 "atau 4" dan kemudian menerapkan melihat.

Bagaimana saya harus melakukan itu?

Finn Gaida
sumber
2
Anda tidak harus membangun setiap "jendela" dua kali. Hanya mereka yang seharusnya cocok dengan ukuran layar yang harus di-relay. Solusinya tampak agak jelas, cukup periksa dimensi jendela dan tambahkan keputusan kasus berdasarkan ukuran yang dikembalikan.
Hingga
1
Yah, pada dasarnya itu benar, tetapi saya ingin menggunakan ukuran layar ekstra dengan cara yang sama sekali berbeda, seperti yang dapat Anda lakukan dengan layar lanskap.
Finn Gaida
Periksa URL ini: stackoverflow.com/questions/4779221/…
ios_av
Haruskah pertanyaan ini diperbarui sesuai dengan perangkat baru? Misalnya "Bagaimana mendeteksi perangkat iOS berdasarkan ukuran layar"?
hfossli

Jawaban:

467

Pertama-tama, Anda tidak harus membangun kembali semua tampilan Anda agar sesuai dengan layar baru, atau menggunakan tampilan yang berbeda untuk ukuran layar yang berbeda.

Gunakan kemampuan pengubahan ukuran otomatis iOS, sehingga tampilan Anda dapat menyesuaikan, dan mengadaptasi ukuran layar apa pun.

Itu tidak terlalu sulit, baca beberapa dokumentasi tentang itu. Ini akan menghemat banyak waktu.

iOS 6 juga menawarkan fitur-fitur baru tentang ini.
Pastikan untuk membaca changelog API iOS 6 di situs web Pengembang Apple.
Dan periksa kemampuan iOS 6 AutoLayout baru .

Yang mengatakan, jika Anda benar-benar perlu mendeteksi iPhone 5, Anda cukup mengandalkan ukuran layar .

[ [ UIScreen mainScreen ] bounds ].size.height

Layar iPhone 5 memiliki ketinggian 568.
Anda dapat membayangkan makro, untuk menyederhanakan semua ini:

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

Penggunaan fabsdengan epsilon ada di sini untuk mencegah kesalahan presisi, saat membandingkan titik apung, seperti yang ditunjukkan dalam komentar oleh H2CO3.

Jadi mulai sekarang Anda bisa menggunakannya dalam pernyataan if / else standar:

if( IS_IPHONE_5 )
{}
else
{}

Edit - Deteksi yang lebih baik

Seperti yang dinyatakan oleh beberapa orang, ini hanya mendeteksi layar lebar , bukan iPhone 5 yang sebenarnya.

Versi iPod touch berikutnya mungkin juga memiliki layar seperti itu, jadi kami dapat menggunakan set makro lain.

Mari kita ganti nama makro asli IS_WIDESCREEN:

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

Dan mari kita tambahkan makro deteksi model:

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

Dengan cara ini, kami dapat memastikan kami memiliki model iPhone DAN layar lebar, dan kami dapat mendefinisikan ulang IS_IPHONE_5makro:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Perhatikan juga, seperti yang dinyatakan oleh @ LearnCocos2D, makro ini tidak akan berfungsi jika aplikasi tidak dioptimalkan untuk layar iPhone 5 (tidak ada gambar [email protected]), karena ukuran layarnya masih 320x480 dalam kondisi seperti itu. sebuah kasus.

Saya tidak berpikir ini mungkin menjadi masalah, karena saya tidak melihat mengapa kami ingin mendeteksi iPhone 5 di aplikasi yang tidak dioptimalkan.

PENTING - Dukungan iOS 8

Di iOS 8, boundsproperti UIScreenkelas sekarang mencerminkan orientasi perangkat .
Jadi jelas, kode sebelumnya tidak akan berfungsi di luar kotak.

Untuk memperbaikinya, Anda cukup menggunakan nativeBoundsproperti baru , alih-alih bounds, karena tidak akan berubah dengan orientasi, dan karena didasarkan pada mode potret-up.
Perhatikan bahwa dimensi nativeBoundsdiukur dalam piksel, jadi untuk iPhone 5 tingginya akan menjadi 1136, bukan 568.

Jika Anda juga menargetkan iOS 7 atau lebih rendah, pastikan untuk menggunakan deteksi fitur, karena panggilan nativeBoundssebelum iOS 8 akan membuat aplikasi Anda macet:

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

Anda dapat mengadaptasi makro sebelumnya dengan cara berikut:

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

Dan jelas, jika Anda perlu mendeteksi iPhone 6 atau 6 Plus, gunakan ukuran layar yang sesuai.

Dibuat
sumber
7
Ini salah, Anda harus menggunakan#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser
28
@ H2CO3: Perhatikan bahwa perbandingan ke DBL_EPSILONtidak diperlukan di sini, dan ==perbandingan tidak akan gagal: hanya perlu melakukan perbandingan menggunakan perbedaan dengan cara ini jika nilai floating point tidak dapat dinyatakan sebagai angka yang tepat (seperti 1.0/3.0*3.0misalnya). Baca artikel ini untuk info lebih lanjut;)
AliSoftware
2
jawaban ini tidak benar. mengapa begitu banyak acungan jempol? Anda tidak bisa hanya menggunakan ketinggian untuk menentukan apakah itu layar lebar. Bung ...
OMGPOP
5
Bolehkah saya menambahkan: Jika Anda ingin ini berfungsi dengan simulator, gunakan ini: #define IS_IPHONE (([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone"]) || ([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone Simulator"]))
david
31
Jawaban ini gila. Hal ini tentang merekomendasikan untuk tidak membandingkan jenis float khusus ini (yang dalam kenyataannya adalah - dan jika Anda tahu Apple harus tahu bahwa selalu akan menjadi - bilangan bulat) dengan == adalah omong kosong dan hal-hal yang terlalu rumit. Juga, saya pikir lebih baik menggunakan UI_USER_INTERFACE_IDIOM () untuk deteksi iPhone karena berfungsi dengan baik pada perangkat dan simulator (dan mungkin lebih cepat daripada pendekatan UIDevice). Ini berfungsi dengan baik dan lebih mudah dibaca: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez
232

Diuji dan dirancang untuk kombinasi SDK dan OS:

Cepat

Jenis iPad ditambahkan. iPad 2 dan iPad mini adalah iPad non-retina. Sementara iPad Mini 2 & di atasnya, iPad 3, 4, iPad Air, Air 2, Air 3, dan iPad Pro 9.7 memiliki resolusi logis yang sama yaitu 1024. iPad Pro memiliki panjang maksimum 1366. Referensi

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

Lihat beraksi https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Catatan: Jika misalnya iPhone 6 dalam mode diperbesar, UI adalah versi diperbesar dari iPhone 5. Fungsi-fungsi ini tidak menentukan jenis perangkat, tetapi mode tampilan sehingga iPhone 5 adalah hasil yang diinginkan dalam contoh ini.

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

Penggunaan: http://pastie.org/9687735

Catatan: Jika misalnya iPhone 6 dalam mode diperbesar, UI adalah versi diperbesar dari iPhone 5. Fungsi-fungsi ini tidak menentukan jenis perangkat, tetapi mode tampilan sehingga iPhone 5 adalah hasil yang diinginkan dalam contoh ini.

hfossli
sumber
1
iPhone 5 akan melaporkan ukuran layar 480x320 biasa, tanpa gambar default baru. Bagi saya ini adalah perilaku yang diinginkan.
hfossli
3
Tambahan yang mungkin berguna adalah #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)yang akan membantu menentukan perbedaan antara iPhone4 dan iPhone5 dan iPad Retina dan non-retina
bshirley
1
Saya tidak setuju. Saya pikir terminologi 'layar lebar' harus ditinggalkan karena cepat usang.
hfossli
1
@Ulamat seperti itulah perilaku iOS 8. Gunakan SCREEN_MAX_LENGTHuntuk mendapatkan 568 di semua rotasi pada iPhone 5.
hfossli
1
@MattParkins Saya sarankan menggunakan model yang lebih kuat memeriksa stackoverflow.com/questions/13366976/… .
hfossli
69

Solusi yang sangat sederhana

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}
Samrat Mazumdar
sumber
1
haha pendek dan sederhana, melakukan hal yang sama :) berdebar untuk menjaga overhead tetap rendah! menempatkan barang di makro bukanlah tantangan ...
benjamin.ludwig
2
Yah tidak menempatkan hal-hal di makro atau fungsi cenderung tidak KERING ... Dari saat Anda perlu melakukan pemeriksaan ini lebih dari sekali ...
hfossli
Yup, tetapi definisikan makro seperti yang ditunjukkan di atas, lebih mudah dan mudah, Anda tidak perlu menempelkan ini jika ... setiap waktu.
Resty
Terima kasih, Anda menyelamatkan hidup saya: D, Tapi saya tidak tahu mengapa Makro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] terikat] .size.height == 568.0) ==> Tidak bekerja di simulator iOS 7.1, sebelumnya bahwa saya masih mengerjakan XCode 4.6. OMG iOS 7.1 & Xcode 5
Linh Nguyen
jawaban yang diperbarui di bawah ini untuk memperhitungkan iPhone 6 dan 6 plus ukuran layar
Sam B
28

Kita sekarang perlu memperhitungkan ukuran layar iPhone 6 dan 6Plus. Inilah jawaban yang diperbarui

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
}

Beberapa info bermanfaat

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"
Sam B
sumber
itu hanya tidak bekerja untuk saya iPhone 5 memutuskan karena 4 iPhone 6+ tidak memutuskan sama sekali Oh saya mengerti saya di lanskap saya harus mengubah tinggi dengan lebar :)
ColdSteel
jika aplikasi Anda dalam mode lansekap maka pastikan Anda mengubah result.height to result.width
Sam B
hmm .. pada iPhone 4 (iOS 6.0) tidak bertukar :( bisa iOS 6.0 prob atau iPhone 4?
ColdSteel
Oke saya memeriksa tampilan hanya di iOS 8 dan lebih besar
ColdSteel
iPhone 6 memberi tinggi = 568
MaxEcho
15

Saya telah mengambil kebebasan untuk menempatkan makro oleh Macmade ke dalam fungsi C, dan beri nama dengan benar karena mendeteksi ketersediaan layar lebar dan TIDAK perlu iPhone 5.

Makro juga tidak mendeteksi berjalan pada iPhone 5 jika proyek tidak menyertakan [email protected] . Tanpa gambar Default baru, iPhone 5 akan melaporkan ukuran layar 480x320 biasa (dalam poin). Jadi pemeriksaan tidak hanya untuk ketersediaan layar lebar tetapi untuk mode layar lebar yang diaktifkan juga.

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}
LearnCocos2D
sumber
Saya masih lebih suka macro, untuk alasan kinerja. Silakan lihat hasil edit untuk jawaban saya. Itu juga memeriksa model.
Macmade
1
Anda juga benar mengatakan iPhone 5 akan melaporkan ukuran layar 480x320 biasa, tanpa gambar default baru. Tapi saya pikir tidak ada gunanya mendeteksi iPhone 5 di aplikasi yang tidak dioptimalkan. :)
Macmade
@Macmade Memang, tidak ada gunanya, tapi ada baiknya diingat jika deteksi tidak berfungsi. Juga, fungsi bisa inlined. Mereka juga akan digarisbawahi di mana pengoptimal kompiler menganggap itu ide yang bagus dan di mana ia bisa tahu itu diizinkan (mis. Fungsi ada di modul yang sama). Menerapkan hal-hal seperti ini melalui fungsi kadang-kadang dapat membawa pemeriksaan tipe tambahan.
Ivan Vučica
4
Pertanyaan terkait kinerja adalah, mengapa Anda menjalankan pemeriksaan ini ribuan kali selama render loop Anda? Jika tidak, kinerja adalah masalah dan kejelasan dan menghindari efek samping yang lebih penting.
LearnCocos2D
Saya memberi Anda +1 untuk ini karena saya lebih suka fungsi terpisah daripada makro, tetapi saya harus menunjukkan bahwa itu tidak benar atau lengkap. Untuk mendeteksi layar lebar, jangan lihat ketinggian layar. Alih-alih, lihat rasio aspek dan kembalikan benar hanya jika rasio aspek lebih besar dari atau sama dengan 16: 9.
Todd Lehman
11

Berikut adalah kode kami, uji lulus pada ios7 / ios8 untuk iphone4, iphone5, ipad, iphone6, iphone6p, tidak masalah pada perangkat atau simulator:

#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 )
Jahe
sumber
Saya menguji pada iPhone 6P dan pernyataan if saya jatuh ke kondisi IS_IPHONE_5? Bagaimana ini bisa terjadi, kode Anda terlihat bagus? Saya melakukan copy dan paste langsung dengan if / else dan saya tahu ponsel saya 6 plus menjalankan iOS 8.3.
whyoz
7

Saya menggunakan jawaban hfossli dan menerjemahkannya ke 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)
Borbea
sumber
6

ini adalah makro untuk proyek cocos2d saya. harus sama untuk aplikasi lain.

#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))
OMGPOP
sumber
5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}
Pengembang D-eptde
sumber
3

Di Swift, proyek iOS 8+ saya ingin membuat ekstensi aktif UIScreen, seperti:

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

}

(CATATAN: nativeBoundsdalam piksel).

Dan kodenya akan seperti:

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

Jadi kodenya memperjelas bahwa ini adalah pemeriksaan untuk layar utama, bukan untuk model perangkat.

zubko
sumber
2

Meminjam dari jawaban Samrat Mazumdar, berikut adalah metode singkat yang memperkirakan ukuran layar perangkat. Ini bekerja dengan perangkat terbaru, tetapi mungkin gagal pada perangkat yang akan datang (karena semua metode menebak mungkin). Ini juga akan menjadi bingung jika perangkat sedang dicerminkan (mengembalikan ukuran layar perangkat, bukan ukuran layar cermin)

#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
    }
} 
Jeff Hay
sumber
Perlu revisi untuk iPad mini yang, saya tidak percaya Anda akan dapat menentukan di manor ini.
Daniel
Ya, iPad mini memiliki resolusi yang sama dengan iPad2, jadi metode ini tidak berfungsi untuk itu. Tidak yakin bagaimana menangani kasing itu sekarang ...
Jeff Hay
1
Kamu tidak seharusnya. Anda dapat memeriksa pengidentifikasi perangkat untuk pembelian "iPad 2,5" juga Anda harus memeriksa 2,6 dan 2,7 - versi wifi saja, gsm dan CDMA. Tetapi itu berarti mini iPad berikutnya akan dirilis dan Anda harus memperbarui ke hard code ke pengidentifikasi tersebut yang tidak dapat Anda ketahui sebelumnya. Anda tidak dapat secara terus-menerus mengetahui kapan Anda menggunakan iPad mini karena Anda benar-benar tidak boleh mencoba "mengoptimalkan" untuk layar yang lebih kecil
Daniel
2

Saya pikir itu harus baik jika makro ini akan berfungsi di perangkat dan simulator, di bawah ini solusinya.

#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)
Bhavesh Dhaduk
sumber
2

Saya menemukan bahwa jawaban tidak termasuk kasus khusus untuk Simulator.

#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 )
valvoline
sumber
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;

}
Mubin Shaikh
sumber
iPhone5 = FALSE;tidak perlu karena variabel sudah memiliki nilai itu jika tidak berubah
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

     }
Nithin M Keloth
sumber
1

Mengandalkan ukuran itu salah dalam banyak tingkatan. Bagaimana kalau kita bertanya ke sistem?

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

Diambil dari Cara terbaik untuk mendeteksi tipe perangkat keras, iPhone4 atau iPhone5? , jawaban edzio27.

3d0
sumber
1

Dengan cara ini Anda dapat mendeteksi keluarga perangkat.

    #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
Xeieshan
sumber
1

Jika proyek dibuat menggunakan Xcode 6, maka gunakan kode yang disebutkan di bawah ini untuk mendeteksi perangkat ..

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

Jika proyek dibuat dalam Xcode 5 dan dibuka di Xcode 6, maka gunakan kode yang disebutkan di bawah ini untuk mendeteksi perangkat. (Kode ini berfungsi jika tidak ada gambar peluncuran untuk iPhone 6,6+ ditugaskan)

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

Jika Anda masih menggunakan Xcode 5 secara bersamaan maka gunakan kode berikut untuk mendeteksi perangkat (iPhone 6 dan 6+ tidak akan terdeteksi)

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

}
Aritra Das
sumber
1
  1. Tambahkan 'File Swift Baru' -> AppDelegateEx.swift

  2. tambahkan ekstensi ke 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. pemakaian:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }
William Hu
sumber
1

Di Swift 3 Anda dapat menggunakan KRDeviceType kelas sederhana saya.

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

Ini didokumentasikan dengan baik dan mendukung operator ==,> =, <=.

Misalnya untuk mendeteksi jika perangkat memiliki batasan iPhone 6 / 6s / 7, Anda dapat menggunakan perbandingan berikut:

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

Untuk mendeteksi apakah perangkat memiliki batasan iPhone 5 / 5S / SE atau yang lebih lama (iPhone 4s) Anda dapat menggunakan perbandingan berikutnya:

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

Ini telah dijawab ratusan kali tetapi solusi ini bekerja paling baik untuk saya dan membantu mengatasi masalah ketika perangkat baru diperkenalkan dan saya tidak memiliki ukuran yang ditentukan.

Pembantu 5 Swift:

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

Ini karena mudah untuk menghafal ukuran inci ponsel, seperti, perangkat "5,5 inci" atau "4,7 inci" tetapi sulit untuk mengingat ukuran piksel yang tepat.

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

Ini juga memberi Anda kesempatan untuk melakukan sesuatu seperti ini:

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

The default: mencoba untuk menggunakan ukuran layar dan skala untuk mencoba dan menghitung inci diagonal. Ini kalau-kalau beberapa ukuran perangkat baru muncul, itu akan mencoba yang terbaik untuk menentukan dan kode, seperti contoh terakhir, harus tetap berfungsi.

William T.
sumber
0

gunakan Kode berikut:

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
}
Laszlo
sumber
0

Berikut ini adalah pengujian perangkat yang benar, tanpa tergantung pada orientasinya

- (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;
}
Pawel Molodkin
sumber
-2

Digunakan untuk mendeteksi Perangkat iPhone dan iPad dari semua ayat.

#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) 
Vaibhav Sharma
sumber
iPhone 6 tidak memiliki layar retina?
vikingosegundo
iPhone6 ​​memiliki tampilan ratina (@ 2X). dan iPhone6 ​​plus memiliki layar HD (@ 3X).
Vaibhav Sharma
Jadi jika diuji untuk IS_RETINAiPhone 6 plus, kode 1x dieksekusi?
vikingosegundo
Lihat Tautan Ini. stackoverflow.com/questions/25756589/…
Vaibhav Sharma
1
Anda tidak mendapatkannya: aturan Anda akan menghasilkan @1x, di mana ia seharusnya menghasilkan @3x.
Lagi