İPhone 5 (geniş ekran cihazlar) nasıl algılanır?


300

XCode 4.5 GM'ye geçtim ve şimdi '4 "Retina' boyutunu film şeridindeki görünüm denetleyicinize uygulayabileceğinizi öğrendim.

Şimdi hem iPhone 4 hem de 5 üzerinde çalışan bir uygulama oluşturmak istersem, elbette her pencereyi iki kez oluşturmam gerekiyor, ancak kullanıcının 3.5 "veya 4" ekranlı bir iPhone'a sahip olup olmadığını tespit edip görünüm.

Bunu nasıl yapmalıyım?


2
Her bir "pencereyi" iki kez oluşturmak zorunda değilsiniz. Yalnızca ekran boyutuyla tam olarak eşleşmesi gerekenlerin yönlendirilmesi gerekir. Çözüm oldukça açık görünüyor, sadece pencere boyutlarını kontrol edin ve iade edilen boyuta göre bir vaka kararı ekleyin.
Till

1
Temel olarak bu doğru, ama ekstra ekran boyutunu tamamen farklı bir şekilde kullanmak istiyorum, tıpkı bir yatay ekranla yapabileceğiniz gibi.
Finn Gaida


Bu soru yeni cihazlara göre güncellenmeli mi? Örneğin "iOS cihazını ekran boyutuna göre nasıl tespit edebilirim?"
14:11, hfossli

Yanıtlar:


467

Her şeyden önce, tüm ekranlarınızı yeni bir ekrana sığacak şekilde yeniden oluşturmamalı veya farklı ekran boyutları için farklı görünümler kullanmamalısınız.

İOS'unuzun otomatik yeniden boyutlandırma özelliklerini kullanın , böylece görünümleriniz herhangi bir ekran boyutunu ayarlayabilir ve uyarlayabilir.

Bu çok zor değil, bununla ilgili bazı belgeleri okuyun . Size çok zaman kazandıracak.

iOS 6 da bununla ilgili yeni özellikler sunuyor. Apple Developer web sitesinde iOS 6 API değişiklik günlüğünü
okuduğunuzdan emin olun . Ayrıca yeni iOS 6 Otomatik Düzenleme özelliklerini kontrol edin .

Bununla birlikte, iPhone 5'i gerçekten algılamanız gerekiyorsa, ekran boyutuna güvenebilirsiniz .

[ [ UIScreen mainScreen ] bounds ].size.height

İPhone 5'in ekranı 568 yüksekliğe sahip.
Tüm bunları basitleştirmek için bir makro hayal edebilirsiniz:

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

fabsEpsilon ile kullanımı, kayan noktaları karşılaştırırken H2CO3'ün yorumlarında belirtildiği gibi hassas hataları önlemek için buradadır.

Artık bundan sonra standart if / else ifadelerinde kullanabilirsiniz:

if( IS_IPHONE_5 )
{}
else
{}

Düzenle - Daha iyi algılama

Bazı insanlar tarafından belirtildiği gibi, bu gerçek bir iPhone 5'i değil , sadece geniş bir ekranı algılar .

İPod touch'ın sonraki sürümlerinde de böyle bir ekran olabilir, bu yüzden başka bir makro seti kullanabiliriz.

Orijinal makroyu yeniden adlandıralım IS_WIDESCREEN:

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

Ve model algılama makroları ekleyelim:

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

Bu şekilde, bir iPhone modelimiz ve geniş ekranımız olduğundan emin olabiliriz ve IS_IPHONE_5makroyu yeniden tanımlayabiliriz :

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

Ayrıca, @ LearnCocos2D tarafından belirtildiği gibi, uygulama iPhone 5 ekranı için optimize edilmemişse (Varsayılan-568h@2x.png resmi eksik) bu makroların çalışmadığı için ekran boyutu hala 320x480 olacaktır. bir olgu.

Optimize edilmemiş bir uygulamada neden bir iPhone 5'i tespit etmek istediğimizi anlamadığım için bunun bir sorun olabileceğini düşünmüyorum.

ÖNEMLİ - iOS 8 desteği

İOS 8'de, sınıfın boundsözelliği UIScreenartık aygıt yönünü yansıtıyor .
Açıkçası, önceki kod kutunun dışında çalışmayacak.

Bunu düzeltmek için, yönlendirmeyle değişmeyeceğinden ve bir portre modunu temel aldığı için yeni nativeBoundsözelliği kullanabilirsiniz bounds.
Boyutlarının nativeBoundspiksel cinsinden ölçüldüğüne dikkat edin, bu nedenle iPhone 5 için yükseklik 568 yerine 1136 olacaktır .

Ayrıca iOS 7 veya daha düşük bir sürümü hedefliyorsanız, nativeBoundsiOS 8'den önce aramak uygulamanızın çökmesine neden olacağından özellik algılamayı kullandığınızdan emin olun :

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

Önceki makroları aşağıdaki şekilde uyarlayabilirsiniz:

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

Açıkçası, bir iPhone 6 veya 6 Plus'ı tespit etmeniz gerekiyorsa, ilgili ekran boyutlarını kullanın.


7
Bu yanlış, kullanmanız gerekecek#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3: Karşılaştırma için Not bu DBL_EPSILONburada gerekli değildir, ve bu ==karşılaştırma olacak olup başarısız: kayan nokta değeri (gibi bir tam sayı olarak ifade edilemez eğer farkları bu şekilde kullanılarak bir karşılaştırma yapmak için sadece gerekli olan 1.0/3.0*3.0gibi). Daha fazla bilgi için bu makaleyi okuyun ;)
AliSoftware

2
bu cevap doğru değil. neden bu kadar çok başparmak aldı? geniş ekran olup olmadığını belirlemek için yalnızca yüksekliği kullanamazsınız. dude ...
OMGPOP

5
Ekleyebilir miyim: Bunun simülatörle çalışmasını istiyorsanız şunu kullanın: #define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString: @ "iPhone"]) || ([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone Simulator"]))
david

31
Bu cevap delilik. Bu belirli şamandıraları (gerçekte - ve Apple'ın her zaman olacağını bilmelidir) tamsayılar olduğunu karşılaştırmamanızı tavsiye etmekle ilgili bu şeyler == saçmalıktır ve işleri karmaşıklaştırır. Ayrıca, hem cihazda hem de simülatörde (ve UIDevice yaklaşımından daha hızlı olabilir) iPhone tespiti için UI_USER_INTERFACE_IDIOM () kullanmanın daha iyi olduğunu düşünüyorum. Bu iyi çalışıyor ve okunması çok daha kolay: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez

232

Herhangi bir SDK ve OS kombinasyonu için test edilmiş ve tasarlanmıştır:

hızlı

İPad türleri eklendi. iPad 2 ve iPad mini retina olmayan iPad'lerdir. İPad Mini 2 ve üstü, iPad 3, 4, iPad Air, Air 2, Air 3 ve iPad Pro 9.7 1024 ile aynı mantıksal çözünürlüğe sahiptir. İPad Pro'nun maksimum uzunluğu 1366'dır. Referans

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

Uygulamada görün https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Not: Örneğin, iPhone 6 yakınlaştırılmış moddaysa, kullanıcı arabirimi iPhone 5'in yakınlaştırılmış bir sürümüdür. Bu işlevler aygıt türünü belirlemez, ancak görüntüleme modu bu nedenle bu örnekte iPhone 5 için istenen sonuçtur.

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)

Kullanım: http://pastie.org/9687735

Not: Örneğin, iPhone 6 yakınlaştırılmış moddaysa, kullanıcı arabirimi iPhone 5'in yakınlaştırılmış bir sürümüdür. Bu işlevler aygıt türünü belirlemez, ancak görüntüleme modu bu nedenle bu örnekte iPhone 5 için istenen sonuçtur.


1
iPhone 5, yeni varsayılan görüntü olmadan normal bir 480x320 ekran boyutu bildirecektir. Bana göre bu istenen davranış.
hfossli

3
Muhtemelen yararlı bir ekleme, #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)hem iPhone4 hem de iPhone5 ve iPad Retina ve retina olmayanlar arasındaki farkın belirlenmesine yardımcı olacak
bshirley

1
Katılmıyorum. Bence 'geniş ekran' terminolojisi hızla modası geçmiş olduğu için dışarıda bırakılmalıdır.
hfossli

1
@Dvole, iOS 8'in işleyiş şekli budur. SCREEN_MAX_LENGTHIPhone 5'teki tüm rotasyonlarda 568 almak için kullanın
hfossli

1
@MattParkins Daha sağlam model denetimleri kullanmanızı öneririm stackoverflow.com/questions/13366976/… .
hfossli

69

Gerçekten basit bir çözüm

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 kısa ve basit, aynısını yaptı :) havai düşük tutmak için thumps up! makroya bir şeyler koymak zor değil ...
benjamin.ludwig

2
Şeyleri makroya veya fonksiyonlara
koymamak

Evet, ama yukarıda gösterildiği gibi makro tanımlayın, daha rahat ve kolaydır, u ... bunu her zaman yapıştırmanız gerekmez.
Resty

Teşekkürler, Hayatımı kurtardın: D, Ama neden bilmiyorum Makro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] sınırları] .size.height == 568.0) ==> Daha önce simülatör iOS 7.1'de çalışmıyor hala XCode 4.6 üzerinde çalışıyorum. OMG iOS 7.1 ve Xcode 5
Linh Nguyen

iPhone 6 ve 6 artı ekran boyutlarını açıklamak için aşağıdaki güncellenmiş cevap
Sam B

28

Şimdi iPhone 6 ve 6Plus ekran boyutlarını hesaba katmamız gerekiyor. İşte güncellenmiş bir cevap

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
}

Bazı faydalı bilgiler

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"

sadece benim için çalışmıyor iPhone 5 4 olarak karar verdi iPhone 6+ hiç karar vermedi Oh Anladım Ben manzaradayım Genişlikle yüksekliği değiştirmeliyim :)
ColdSteel

uygulama yatay modda ise o zaman emin result.width için result.height değiştirmek yapmak
Sam B

hmm .. iPhone 4'te (iOS 6.0) değişmedi :( iOS 6.0 prob veya iPhone 4 olabilir mi?
ColdSteel

Tamam, yalnızca iOS 8 ve daha yeni sürümlerde değiştirilen görünümü kontrol ettim
ColdSteel

iPhone 6 yükseklik veriyor = 568
MaxEcho

15

Macmade tarafından makroyu bir C fonksiyonuna koyma özgürlüğünü aldım ve geniş ekran kullanılabilirliğini tespit ettiğinden ve iPhone 5'i DEĞİLDİR diye düzgün bir şekilde adlandırdım .

Makro, projenin Default-568h@2x.png dosyasını içermemesi durumunda bir iPhone 5 üzerinde çalıştığını da algılamaz . Yeni Varsayılan görüntü olmadan, iPhone 5 normal bir 480x320 ekran boyutu (nokta cinsinden) bildirecektir. Bu nedenle, kontrol yalnızca geniş ekran kullanılabilirliği için değil, aynı zamanda geniş ekran modunun etkinleştirilmesi için de geçerlidir.

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

Performans nedenleriyle hala makroları tercih ediyorum. Lütfen cevabımın düzenlemesine bakın. Ayrıca modeli kontrol eder.
Macmade

1
Ayrıca, iPhone 5'in yeni varsayılan görüntü olmadan normal bir 480x320 ekran boyutunu bildireceğini söyleyebilirsiniz. Ancak optimize edilmemiş bir uygulamada bir iPhone 5'i tespit etmenin bir anlamı olmadığını düşünüyorum. :)
Macmade

@Macmade Gerçekten, hiçbir anlamı yok, ancak tespitin işe yaramadığı durumlarda akılda tutmak iyi. Ayrıca, fonksiyonlar inlined olabilir . Ayrıca, derleyicinin optimize edicisinin iyi bir fikir olduğunu düşündüğü ve izin verilebilir olduğunu nereden bildikleri (örneğin işlev aynı modülde) nerede sıralanır. Bu tür şeyleri bir işlev aracılığıyla uygulamak bazen ek tür denetimi getirebilir.
Ivan Vučica

4
Performansla ilgili soru, bu döngüyü oluşturma döngünüz sırasında neden binlerce kez çalıştırdınız? Aksi takdirde, performans bir sorun ve netliktir ve daha büyük öneme sahip yan etkilerden kaçınır.
LearnCocos2D

Bunun için size bir +1 verdim çünkü makro yerine ayrı bir işlevi seviyorum, ancak bunun gerçekten doğru veya eksiksiz olmadığını belirtmeliyim. Geniş ekran algılamak için, yok ekranın yüksekliği bak. Bunun yerine, en boy oranına bakın ve yalnızca en boy oranı 16: 9'dan büyük veya ona eşitse true değerini döndürün.
Todd Lehman

11

İşte kodlarımız, testler ios7 / ios8 için iphone4, iphone5, ipad, iphone6, iphone6p, cihazlarda veya simülatörde olursa olsun:

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

Ben bir iPhone 6P test ve benim if ifadesi IS_IPHONE_5 koşulu düşüyor? Bu nasıl olabilir, kod iyi görünüyor mu? Düz bir kopyasını yaptım ve basit bir if / else ile yapıştırdım ve telefonumun iOS 8.3 çalıştıran bir 6 artı olduğunu biliyorum.
whyoz

7

Hfossli'nin cevabını kullandım ve Swift'e çevirdim

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

Bu benim cocos2d projem için bir makro. diğer uygulamalar için aynı olmalıdır.

#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

Swift, iOS 8+ projesinde aşağıdakiler gibi bir uzantı yapmak UIScreenistiyorum:

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

}

(NOT: nativeBoundspiksel cinsindendir).

Ve sonra kod şöyle olacak:

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

Böylece kod, bunun cihaz modeli için değil, ana ekran için bir kontrol olduğunu açıkça ortaya koymaktadır.


2

Samrat Mazumdar'ın cevabından ödünç alarak, cihazın ekran boyutunu tahmin eden kısa bir yöntem var. En son cihazlarla çalışır, ancak gelecekteki cihazlarda başarısız olabilir (tüm tahmin yöntemleri gibi). Cihaz yansıtılırsa da karışacaktır (yansıtılan ekran boyutunu değil, cihazın ekran boyutunu döndürür)

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

İPad mini için revizyon gerekiyor, bu malikanede belirleyebileceğinize inanmıyorum.
Daniel

Evet, iPad mini, iPad2 ile aynı çözünürlüğe sahiptir, bu nedenle bu yöntem bunun için çalışmaz. Şu anda bu davanın nasıl ele alınacağından emin değilim ...
Jeff Hay

1
Yapmanız gerekmiyor. "İPad 2,5" satın almak için cihaz tanımlayıcısını da kontrol edebilirsiniz, ayrıca 2,6 ve 2,7'yi kontrol etmeniz gerekir - sadece wifi sürümü, gsm ve CDMA. Ancak bu, bir sonraki iPad mini'nin piyasaya sürüleceği ve önceden bilmediğiniz bu tanımlayıcıların sabit kodunu güncellemeniz gerektiği anlamına geliyor. Bir iPad mini'de olduğunuzda sürekli olarak bilemezsiniz çünkü gerçekten daha küçük ekran için "optimize etmeye" çalışmamalısınız
Daniel

2

Bu makronun cihazda ve simülatörde çalışmasının iyi olması gerektiğini düşünüyorum, aşağıda çözüm var.

#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

Yanıtların Simülatörler için özel bir durum içermediğini buldum.

#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;gereksizdir çünkü değişken değiştirilmediyse zaten bu değere sahiptir
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

Bu şekilde cihaz ailesini tespit edebilirsiniz.

    #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

Proje Xcode 6 kullanılarak oluşturulmuşsa, cihazları tespit etmek için aşağıda belirtilen kodu kullanın.

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

Proje Xcode 5'te oluşturulmuş ve Xcode 6'da açılmışsa, cihazları algılamak için aşağıda belirtilen kodu kullanın. (Bu kod, iPhone 6,6+ için başlatma görüntüleri atanmamışsa çalışır)

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

Hala Xcode 5'i birlikte kullanıyorsanız, cihazları tespit etmek için aşağıdaki kodu kullanın (iPhone 6 ve 6+ algılanmayacaktır)

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. 'Yeni Swift Dosyası' ekleyin -> AppDelegateEx.swift

  2. bir uzantı ekle 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. kullanımı:

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

1

Swift 3'te basit sınıf KRDeviceType'ımı kullanabilirsiniz.

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

İyi belgelenmiştir ve ==,> =, <= operatörlerini destekler.

Örneğin, cihazın iPhone 6 / 6s / 7 sınırlarına sahip olup olmadığını tespit etmek için sadece bir sonraki karşılaştırmayı kullanabilirsiniz:

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

Cihazda iPhone 5 / 5S / SE veya daha önceki sürümlerin (iPhone 4s) sınırları olup olmadığını tespit etmek için bir sonraki karşılaştırmayı kullanabilirsiniz:

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

1

Bu yüz kere cevaplandı, ancak bu çözüm benim için en iyisini yaptı ve yeni cihazlar tanıtıldığında ve tanımlanmış bir boyutum olmadığında sorunun çözülmesine yardımcı oldu.

Swift 5 Yardımcısı:

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

Bunun nedeni, "5.5 inç" veya "4.7 inç" cihaz gibi bir telefonun inç boyutlarını ezberlemenin kolay olmasıdır, ancak tam piksel boyutlarını hatırlamak zordur.

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

Bu ayrıca size böyle bir şey yapma fırsatı verir:

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

Default: kullanımlara denemek ve diyagonal inç hesaplamak için ekran boyutunu ve ölçek çalışır. Bu, bazı yeni cihaz boyutlarının görünmesi durumunda, en son örneği belirlemek ve kodlamanın yine de çalışması gerekir.


0

aşağıdaki Kodu kullanın:

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

İşte cihazın yönüne bağlı olmadan doğru testi

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

Tüm sürümlerin iPhone ve iPad Cihazlarını tespit etmek için kullanılır.

#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'da retina ekranı yok mu?
vikingosegundo

iPhone6, ratina (@ 2X) ekrana sahip. iPhone6 ​​plus ise HD (@ 3X) ekrana sahip.
Vaibhav Sharma

Yani IS_RETINAbir iPhone 6 plus üzerinde test edilirse , 1x kodu yürütülür?
vikingosegundo


1
bunu elde edemezsiniz: kurallarınız vereceği @1xyerde verilecektir @3x. neyse: sadece kopyalayıp yapıştıracağınız gibi: -1
vikingosegundo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.