iOS wykrywa, czy użytkownik jest na iPadzie

260

Mam aplikację, która działa na iPhonie i iPodzie Touch, może działać na iPadzie Retina i wszystkim, ale musi być jedna regulacja. Muszę wykryć, czy bieżącym urządzeniem jest iPad. Jakiego kodu mogę użyć do wykrycia, czy użytkownik korzysta z iPada na moim komputerze, UIViewControllera następnie odpowiednio go zmienić?

Albert Renshaw
źródło

Odpowiedzi:

589

Istnieje wiele sposobów sprawdzenia, czy urządzeniem jest iPad. To mój ulubiony sposób sprawdzenia, czy urządzenie to tak naprawdę iPad:

if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
    return YES; /* Device is iPad */
}

Sposób w jaki go używam

#define IDIOM    UI_USER_INTERFACE_IDIOM()
#define IPAD     UIUserInterfaceIdiomPad

if ( IDIOM == IPAD ) {
    /* do something specifically for iPad. */
} else {
    /* do something specifically for iPhone or iPod touch. */
}   

Inne przykłady

if ( [(NSString*)[UIDevice currentDevice].model hasPrefix:@"iPad"] ) {
    return YES; /* Device is iPad */
}

#define IPAD     (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
if ( IPAD ) 
     return YES;

Aby uzyskać szybkie rozwiązanie, zobacz tę odpowiedź: https://stackoverflow.com/a/27517536/2057171

WrightsCS
źródło
23
Sposób, w jaki go używasz, nie jest tak wydajny, jak mógłby być. UI_USER_INTERFACE_IDIOM()jest równoważne z ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone). Może być lepiej buforowanie gdzieś wynik: BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; … if (iPad) ….
Marcelo Cantos
7
Używałbym hasPrefix zamiast isEqualToString w twojej ostatniej metodzie. W ten sposób kod działa również na symulatorze.
zbuduj
18
Szybki:if UIDevice.currentDevice().userInterfaceIdiom == .Pad
Pang
2
Godne wykorzystanie makr. Świetny sposób na zaciemnienie kodu.
gnasher729,
2
@ gnasher729 Ponad 500 osób nie zgadza się z tobą. Zamiast wulgarnych komentarzy, dlaczego nie podasz własnej odpowiedzi, ponieważ uważasz, że masz na to lepszy sposób.
WrightsCS,
162

W Swift możesz użyć następujących równości, aby określić rodzaj urządzenia w aplikacjach Universal:

UIDevice.current.userInterfaceIdiom == .phone
// or
UIDevice.current.userInterfaceIdiom == .pad

Użycie byłoby wtedy takie jak:

if UIDevice.current.userInterfaceIdiom == .pad {
    // Available Idioms - .pad, .phone, .tv, .carPlay, .unspecified
    // Implement your logic here
}
Jeehut
źródło
3
Edytuję link do twojej odpowiedzi do zaakceptowanej odpowiedzi. (W ten sposób otrzymasz również kredyt). Mimo że jest to pytanie celowe, wiele osób przeglądających to pytanie pochodzi z Google i może szukać szybkiego rozwiązania! : D
Albert Renshaw,
1
Dziękuję, @AlbertRenshaw. Też tak myślałem. :) Btw: Nie sądzę, że celem tego pytania było zapytanie o Objective-C, ale na iOS (który był wtedy Obj-C). Przynajmniej spodziewałbym się znaleźć odpowiedź pod tym pytaniem również dla Szybkiego.
Jeehut,
Cześć @sevensevens, dziękuję za opinię. Właśnie to wypróbowałem i zadziałało to w XCode 7.2 w iOS 9 w symulatorze. Jakiej wersji XCode używasz? Może to nie działa na starszych XCodes? Dokumenty mówią userInterfaceIdiom„Dostępny w iOS 3.2 i nowszych”. więc to nie powinien być problem.
Jeehut,
A może jest tak, że korzystasz z aplikacji na iPhone'a w symulatorze iPada? W takim przypadku tłumaczyłoby to zamieszanie - ale myślę, że tak też powinno się zachowywać na prawdziwych urządzeniach. Jak zauważa @Yunus Nedim Mehel w komentarzach @Richards, odpowiedź ta .Phonezamiast tego powróci .Pad.
Jeehut,
Przepraszamy - ustawiono symulator na iPhone'a. Muszę przestać wprowadzać zmiany o 2 w
nocy
35

Jest to część UIDevice od iOS 3.2, np .:

[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad
Richard
źródło
4
idiom jest ogólnie lepszy, ale jeśli używasz aplikacji na iPhone'a na iPadzie, to zwróci UIUserInterfaceIdiomPhone.
Yunus Nedim Mehel,
25

Możesz także tego użyć

#define IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
...
if (IPAD) {
   // iPad
} else {
   // iPhone / iPod Touch
}
Chłodny
źródło
24

UI_USER_INTERFACE_IDIOM()zwraca iPada tylko wtedy, gdy aplikacja jest przeznaczona na iPada lub Universal. Jeśli jest to aplikacja na iPhone'a działająca na iPadzie, nie będzie. Zamiast tego powinieneś sprawdzić model.

malhal
źródło
15

Zachowaj ostrożność: jeśli Twoja aplikacja jest kierowana tylko na urządzenia iPhone, iPad działający w trybie zgodnym z iPhone'em zwróci wartość false dla poniższego stwierdzenia:

#define IPAD     UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad

Właściwy sposób na wykrycie fizycznego urządzenia iPad to:

#define IS_IPAD_DEVICE      ([(NSString *)[UIDevice currentDevice].model hasPrefix:@"iPad"])
szczyt
źródło
15

Odkryłem, że niektóre rozwiązania nie działały dla mnie w Symulatorze w Xcode. Zamiast tego działa:

ObjC

NSString *deviceModel = (NSString*)[UIDevice currentDevice].model;

if ([[deviceModel substringWithRange:NSMakeRange(0, 4)] isEqualToString:@"iPad"]) {
    DebugLog(@"iPad");
} else {
    DebugLog(@"iPhone or iPod Touch");
}

Szybki

if UIDevice.current.model.hasPrefix("iPad") {
    print("iPad")
} else {
    print("iPhone or iPod Touch")
}

Również w „Innych przykładach” w Xcode model urządzenia powraca jako „Symulator iPada”, więc powyższa poprawka powinna to rozwiązać.

Andy Davies
źródło
Może Apple zaktualizowało symulator, mówiąc coś w stylu „symulator iPada” lub „iPad 2.1” lub coś w tym rodzaju… jeśli to jest przypadek, którego możesz użyć hasSuffix:@"iPad"zamiast isEqualToString@"iPad"… najlepiej jest zalogować model urządzenia, który symulator zwraca i odchodzi stamtąd ...
Albert Renshaw
8

Wiele sposobów, aby to zrobić w Swift :

Sprawdzamy model poniżej (tutaj możemy przeprowadzić wyszukiwanie z rozróżnianiem wielkości liter):

class func isUserUsingAnIpad() -> Bool {
    let deviceModel = UIDevice.currentDevice().model
    let result: Bool = NSString(string: deviceModel).containsString("iPad")
    return result
}

Sprawdzamy model poniżej (tutaj możemy przeprowadzić wyszukiwanie z rozróżnianiem wielkości liter / niewrażliwości):

    class func isUserUsingAnIpad() -> Bool {
        let deviceModel = UIDevice.currentDevice().model
        let deviceModelNumberOfCharacters: Int = count(deviceModel)
        if deviceModel.rangeOfString("iPad",
                                     options: NSStringCompareOptions.LiteralSearch,
                                     range: Range<String.Index>(start: deviceModel.startIndex,
                                                                end: advance(deviceModel.startIndex, deviceModelNumberOfCharacters)),
                                     locale: nil) != nil {
            return true
        } else {
            return false
        }
   }

UIDevice.currentDevice().userInterfaceIdiomponiżej zwraca iPada tylko wtedy, gdy aplikacja jest na iPada lub Universal. Jeśli jest to aplikacja na iPhone'a uruchomiona na iPadzie, nie będzie. Zamiast tego powinieneś sprawdzić model. :

    class func isUserUsingAnIpad() -> Bool {
        if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
            return true
        } else {
            return false
        }
   }

Poniższy fragment kodu nie kompiluje się, jeśli klasa nie dziedziczy pliku UIViewController, w przeciwnym razie działa dobrze. Niezależnie od tego UI_USER_INTERFACE_IDIOM()zwraca iPada tylko wtedy, gdy aplikacja jest na iPada lub Universal. Jeśli jest to aplikacja na iPhone'a uruchomiona na iPadzie, nie będzie. Zamiast tego powinieneś sprawdzić model. :

class func isUserUsingAnIpad() -> Bool {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad) {
        return true
    } else {
        return false
    }
}
King-Wizard
źródło
2
Nie sądzę, że trzeba szybko przepisywać stare odpowiedzi na pytania oznaczone Cel-C.
Christian Schnorr,
4
Zdecydowanie uważam, że moja odpowiedź jest przydatna, ponieważ po pierwsze wszystkie odpowiedzi są rozproszone po przepełnieniu stosu. Po drugie, to, co działało ze starszymi wersjami iOS, czasami nie działa poprawnie z iOS 8 i nowszym. Przetestowałem więc te rozwiązania i ta odpowiedź może być bardzo przydatna. Więc w ogóle się z tobą nie zgadzam.
King-Wizard
Ponadto składnia jest inna w Swift. Dlatego zawsze przydatne jest wykonanie inteligentnej kopii wklej odpowiedzi i zrozumienie konkretnych aktualnych nakrętek i śrub.
King-Wizard
8

*

W szybkim 3.0

*

 if UIDevice.current.userInterfaceIdiom == .pad {
        //pad
    } else if UIDevice.current.userInterfaceIdiom == .phone {
        //phone
    } else if UIDevice.current.userInterfaceIdiom == .tv {
        //tv
    } else if UIDevice.current.userInterfaceIdiom == .carPlay {
        //CarDisplay
    } else {
        //unspecified
    }
Ashok R.
źródło
8

Wiele odpowiedzi jest dobrych, ale używam tego w swift 4

  1. Utwórz stałą

    struct App {
        static let isRunningOnIpad = UIDevice.current.userInterfaceIdiom == .pad ? true : false
    }
  2. Użyj w ten sposób

    if App.isRunningOnIpad {
        return load(from: .main, identifier: identifier)
    } else {
        return load(from: .ipad, identifier: identifier)
    }

Edycja: zgodnie z sugestią Cœur po prostu utwórz rozszerzenie na UIDevice

extension UIDevice {
    static let isRunningOnIpad = UIDevice.current.userInterfaceIdiom == .pad ? true : false
}
Rohit Sisodia
źródło
3
Po co zawracać sobie Appgłowę strukturą, skoro możesz zrobić to samo z UIDevicerozszerzeniem?
Cœur
3

Możesz sprawdzić rangeOfString, aby zobaczyć, że słowo iPad istnieje w ten sposób.

NSString *deviceModel = (NSString*)[UIDevice currentDevice].model;

if ([deviceModel rangeOfString:@"iPad"].location != NSNotFound)  {
NSLog(@"I am an iPad");
} else {
NSLog(@"I am not an iPad");
}
LearningGuy
źródło
["I am not an iPad" rangeOfString:@"iPad"].location != NSNotFoundzwraca true.
Cœur
2

Jeszcze inny Swifty sposób:

//MARK: -  Device Check
let iPad = UIUserInterfaceIdiom.Pad
let iPhone = UIUserInterfaceIdiom.Phone
@available(iOS 9.0, *) /* AppleTV check is iOS9+ */
let TV = UIUserInterfaceIdiom.TV

extension UIDevice {
    static var type: UIUserInterfaceIdiom 
        { return UIDevice.currentDevice().userInterfaceIdiom }
}

Stosowanie:

if UIDevice.type == iPhone {
    //it's an iPhone!
}

if UIDevice.type == iPad {
    //it's an iPad!
}

if UIDevice.type == TV {
    //it's an TV!
}
Aviel Gross
źródło
2

W Swift 4.2 i Xcode 10

if UIDevice().userInterfaceIdiom == .phone {
    //This is iPhone
} else if UIDevice().userInterfaceIdiom == .pad { 
    //This is iPad
} else if UIDevice().userInterfaceIdiom == .tv {
    //This is Apple TV
}

Jeśli chcesz wykryć określone urządzenie

let screenHeight = UIScreen.main.bounds.size.height
if UIDevice().userInterfaceIdiom == .phone {
    if (screenHeight >= 667) {
        print("iPhone 6 and later")
    } else if (screenHeight == 568) {
        print("SE, 5C, 5S")
    } else if(screenHeight<=480){
        print("4S")
    }
} else if UIDevice().userInterfaceIdiom == .pad { 
    //This is iPad
}
iOS
źródło
1

Dlaczego tak skomplikowane? Tak to robię ...

Swift 4:

var iPad : Bool {
    return UIDevice.current.model.contains("iPad")
}

W ten sposób możesz po prostu powiedzieć if iPad {}

The Ruffus
źródło
1
Uwaga: To pytanie zostało zadane w 2012 r.
Albert Renshaw,
0

W najnowszych wersjach iOS wystarczy dodać UITraitCollection:

extension UITraitCollection {

    var isIpad: Bool {
        return horizontalSizeClass == .regular && verticalSizeClass == .regular
    }
}

a następnie UIViewControllerwystarczy sprawdzić:

if traitCollection.isIpad { ... }
Bartłomiej Semańczyk
źródło
4
Czy działa to również wtedy, gdy aplikacja na iPada działa w trybie podzielonego ekranu? Wtedy pozioma klasa wielkości byłaby zwarta.
Oliver
0
if(UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.pad)
 {
            print("This is iPad")
 }else if (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiom.phone)
 {
            print("This is iPhone");
  }
Rajesh Sharma
źródło