Meu aplicativo iOS usa uma altura personalizada, o UINavigationBar
que leva a alguns problemas no novo iPhone X.
Alguém já sabe como detectar de forma confiável por meio de programação (no Objective-C) se um aplicativo está sendo executado no iPhone X?
EDITAR:
Claro que é possível verificar o tamanho da tela, no entanto, gostaria de saber se existe algum método de "compilação" como TARGET_OS_IPHONE
para detectar o iOS ...
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 812)
NSLog(@"iPhone X");
}
EDIT 2:
Eu não acho que minha pergunta seja uma duplicata da questão vinculada. Obviamente, existem métodos para "medir" diferentes propriedades do dispositivo atual e usar os resultados para decidir qual dispositivo será usado. No entanto, esse não era o ponto real da minha pergunta, como tentei enfatizar na minha primeira edição.
A questão real é: "É possível detectar diretamente se o dispositivo atual é um iPhone X (por exemplo, por algum recurso do SDK) ou preciso usar medições indiretas" ?
Pelas respostas dadas até agora, suponho que a resposta seja "Não, não há métodos diretos. As medidas são o caminho a percorrer".
fonte
Respostas:
Com base na sua pergunta, a resposta é não. Não há métodos diretos. Para mais informações, você pode obter as informações aqui:
e
A altura do iPhone X é 2436 px
Em tamanhos e resoluções de tela do dispositivo :
Em tamanhos e orientações da tela do dispositivo :
Swift 3 e posterior :
Objetivo-C :
Xamarin.iOS :
Com base na sua pergunta, como segue:
Ou use
screenSize.height
como float812.0f
não int812
.Para obter mais informações, consulte a seguinte página nas Diretrizes da interface humana do iOS:
Swift :
Detectar com
topNotch
:Objetivo-C :
ATUALIZAÇÃO :
Não use a
userInterfaceIdiom
propriedade para identificar o tipo de dispositivo, como explica a documentação para userInterfaceIdiom :Ou seja, essa propriedade é usada apenas para identificar o estilo de exibição do aplicativo em execução. No entanto, o aplicativo para iPhone (não o universal) pode ser instalado no dispositivo iPad via App Store; nesse caso, o
userInterfaceIdiom
retornoUIUserInterfaceIdiomPhone
também será.O caminho certo é obter o nome da máquina via
uname
. Verifique o seguinte para obter detalhes:fonte
userInterfaceIdiom
retornoUIUserInterfaceIdiomPhone
também será. Esta resposta está errada.Outra possibilidade, que funciona no iOS 11 e no iOS 12, porque o iPhone X é o único com um entalhe na parte superior e uma inserção de 44. É isso que estou realmente detectando aqui:
Objetivo-C:
Swift 4:
E, é claro, pode ser necessário verificar as inserções da área segura esquerda e direita se estiver na orientação paisagem.
Edit: _window é a UIWindow do AppDelegate, onde essa verificação é feita no aplicativo didFinishLaunchingWithOptions.
Resposta atualizada para iOS 12 para verificar se top> 24 em vez de top> 0.
Editar: no simulador, você pode acessar Hardware, Alternar barra de status de chamada. Fazer isso me mostra que a altura da barra de status não muda no iPhone X no iOS 11 ou no iPhone XS iOS 12 quando está envolvido em uma chamada. Tudo o que muda é o ícone do tempo, que obtém um fundo verde nos dois casos. Aqui está um piscar de olhos:
fonte
if _window.safeAreaInsets != UIEdgeInsets.zero
para permitir qualquer orientação do dispositivo.top
,safeAreaInsets.bottom
será 34 no iPhone X e 0 em outros dispositivosVocê deve realizar diferentes detecções do iPhone X, dependendo da necessidade real.
para lidar com o nível superior (barra de status, barra de navegação) etc.
para lidar com o indicador inicial inferior (tabbar), etc.
para tamanho de fundos, recursos de tela cheia etc.
Nota: eventualmente, misture-o com
UIDevice.current.userInterfaceIdiom == .phone
Nota: esse método requer um storyboard LaunchScreen ou LaunchImages adequado
para proporção de fundos, recursos de rolagem etc.
Nota: esse método requer que haja um storyboard do LaunchScreen ou LaunchImages adequado
para análises, estatísticas, rastreamento etc.
Obtenha o identificador da máquina e compare-o com os valores documentados:
Para incluir o simulador como um iPhone X válido em suas análises:
Para incluir o iPhone XS, XS Max e XR, basta procurar modelos começando com "iPhone11":
para suporte faceID
fonte
return LAContext().biometryType == .typeFaceID
iria funcionar mesmo se o usuário negou canEvaluatePolicy, mas ele não funciona para mim, ele ainda retorna.none
model == "iPhone10,3" || model == "iPhone10,6"
) e, secanUseFaceID
retornar falso, significa que foi negado pelo usuário.Você pode fazer assim para detectar o dispositivo iPhone X de acordo com a dimensão.
Rápido
Objetivo - C
mas ,
Esta não é a maneira suficiente. E se a Apple anunciasse o próximo iPhone com a mesma dimensão do iPhone X. A melhor maneira é usar a cadeia de hardware para detectar o dispositivo.
Para dispositivos mais recentes, a sequência de hardware é a seguinte.
iPhone 8 - iPhone10,1 ou iPhone 10,4
iPhone 8 Plus - iPhone10,2 ou iPhone 10,5
iPhone X - iPhone10,3 ou iPhone10,6
fonte
[UIDevice currentDevice]
vez de[[UIDevice alloc] init]
Verifique o modelo do dispositivo / nome da máquina , NÃO use a contagem de pontos / pixels no seu código diretamente, é código rígido e sem sentido para o hardware do dispositivo , o modelo do dispositivo é o único identificador exclusivo para um tipo de dispositivo correspondente .
Resultado:
Consulte esta resposta .
Implementação de código completo:
fonte
defina IS_IPHONE_X (IS_IPHONE && [[tela principal do UIScreen] limites] .size.height == 812.0)
Nota: - Cuidado, ele funciona bem apenas para orientação retrato
fonte
nativeScale
com3.0
, certo?Depois de analisar todas as respostas, foi isso que acabei fazendo:
Solução (compatível com Swift 4.1)
Usar
Nota
No Pre Swift 4.1, você pode verificar se o aplicativo está sendo executado em um simulador como este:
Do Swift 4.1 em diante, você pode verificar se o aplicativo está sendo executado em um simulador usando a condição da plataforma do ambiente Target :
(o método mais antigo ainda funcionará, mas esse novo método é mais à prova de futuro)
fonte
Todas essas respostas baseadas em dimensões são suscetíveis a comportamentos incorretos em dispositivos futuros. Eles funcionarão hoje, mas e se houver um iPhone no próximo ano com o mesmo tamanho, mas com a câmera etc. embaixo do vidro, para que não haja entalhes? Se a única opção é atualizar o aplicativo, é uma solução ruim para você e seus clientes.
Você também pode verificar a sequência do modelo de hardware como "iPhone10,1", mas isso é problemático porque às vezes a Apple lança números de modelo diferentes para diferentes operadoras em todo o mundo.
A abordagem correta é redesenhar o layout superior ou resolver os problemas que você está tendo com a altura da barra de navegação personalizada (é nisso que eu focaria). Mas, se você decidir não fazer nenhuma dessas coisas, saiba que o que você está fazendo é um truque para que isso funcione hoje e precisará corrigi-lo em algum momento, talvez várias vezes, para manter os hacks trabalhando.
fonte
Resposta SWIFT 4+
iPhone X, XR, XS, XSMAX, 11 Pro, 11 Pro Max:
Nota: Precisa de um dispositivo real para teste
Referência
fonte
Extensão reutilizável SWIFT 4/5 com suporte para iPhone 11
fonte
UIDevice.current.hasHomeButton
Sim, é possível. Faça o download da extensão UIDevice-Hardware (ou instale via CocoaPod 'UIDevice-Hardware') e use:
Observe que isso não funcionará no Simulador, apenas no dispositivo real.
fonte
ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"]
no Simulator para obter os valores reais do Xcode.De acordo com a resposta do @ saswanb, esta é uma versão do Swift 4:
fonte
keyWindow
énil
até o principal controlador de vista chamouviewDidAppear
Eu sei que é apenas uma solução Swift , mas poderia ajudar alguém.
Eu tenho
globals.swift
em todos os projetos e uma das coisas que sempre adiciono éDeviceType
detectar facilmente o dispositivo do usuário:Então, para usá-lo:
Se você usar
LaunchImage
em seu projeto, adicione imagens para todos os dispositivos suportados (como XS Max, XR), poisUIScreen.main.bounds
não retornará o valor adequado sem eles.fonte
if DeviceType.iPhoneX { //do something for iPhone X notch }else{ // don’t do anything about notch }
Todas as respostas que estão usando
height
são apenas metade da história por um motivo. Se você vai verificar assim quando a orientação do dispositivo estiverlandscapeLeft
oulandscapeRight
a verificação falhará, porque aheight
troca é feita com owidth
.É por isso que minha solução se parece com isso no Swift 4.0:
fonte
Você não deve presumir que o único dispositivo lançado pela Apple com uma altura diferente do UINavigationBar será o iPhone X. Tente resolver esse problema usando uma solução mais genérica. Se você deseja que a barra sempre seja 20px maior que a altura padrão, seu código deve adicionar 20px à altura da barra, em vez de defini-la para 64px (44px + 20px).
fonte
fonte
Rápido 3 + 4:
Exemplo:
fonte
fonte
fonte
Geralmente, o programador precisa dele para restringir a parte superior ou inferior, para que esses métodos possam ajudar
Antes do iPhone X, esses métodos retornam: 0
Para o iPhone X: 44 e 34 em conformidade
Em seguida, basta adicionar esses extras às restrições superior ou inferior
fonte
Para quem obtém 2001px em vez de 2436px para a altura dos limites nativos (como eu), é porque você criou seu aplicativo com um SDK mais antigo, antes do iOS 11 (Xcode 8 em vez do Xcode 9). Com um SDK mais antigo, o iOS exibirá os aplicativos com "caixa preta" no iPhone X, em vez de estender a tela de ponta a ponta, além do topo do "encaixe do sensor". Isso reduz o tamanho da tela e é por isso que essa propriedade retorna 2001 em vez de 2436.
A solução mais simples é apenas verificar os dois tamanhos, se você estiver interessado apenas na detecção de dispositivos. Eu usei esse método para detectar o FaceID ao criar com um Xcode SDK mais antigo que não possui o valor ENUM especificando o tipo biométrico. Nessa situação, a detecção do dispositivo usando a altura da tela parecia a melhor maneira de saber se o dispositivo tinha o FaceID vs TouchID sem precisar atualizar o Xcode.
fonte
NÃO use o tamanho do pixel da tela, como sugeriram outras soluções; isso é ruim, pois pode resultar em falsos positivos para dispositivos futuros; não funcionará se o UIWindow ainda não tiver sido renderizado (AppDelegate), não funcionará em aplicativos de paisagem e poderá falhar no simulador se a escala estiver definida.
Em vez disso, criei uma macro para esse fim; é muito fácil de usar e depende de sinalizadores de hardware para evitar os problemas mencionados acima.
Editar: Atualizado para oferecer suporte ao iPhoneX, iPhone XS, iPhoneXR, iPhoneXS Max
Usar:
Sim, sério.
Macro:
Basta copiar e colar isso em qualquer lugar, eu prefiro a parte inferior do meu arquivo .h depois
@end
fonte
if (@available(iOS 11.0, *)) { [UIApplication sharedApplication].keyWindow.safeAreaInsets.top }
Eu elaborei as respostas dos outros e fiz uma extensão rápida no UIDevice. Eu gosto de enums rápidos e "tudo em ordem" e atomizado. Eu criei uma solução que funciona tanto no dispositivo quanto no simulador.
Vantagens: - interface simples, uso, por exemplo
UIDevice.current.isIPhoneX
-UIDeviceModelType
enum permite ampliar facilmente recursos e constantes específicos do modelo que você deseja usar no seu aplicativo, por exemplo, cornerRadiusDesvantagem: - é uma solução específica do modelo, não específica da resolução - por exemplo, se a Apple produzir outro modelo com as mesmas especificações, isso não funcionará corretamente e você precisará adicionar outro modelo para fazer esse trabalho => você precisa atualizar seu aplicativo.
fonte
Mirror
, será mais rápido usarsysctlbyname
como feito na resposta do Cloud9999Strife (e na minha resposta também).Confio na altura do quadro da barra de status para detectar se é um iPhone X:
Isto é para aplicação em retrato. Você também pode verificar o tamanho de acordo com a orientação do dispositivo. Além disso, em outros iPhones, a Barra de status pode estar oculta, portanto a altura do quadro é
0
. No iPhone X, a barra de status nunca fica oculta.fonte
controller
com isso:- (BOOL)prefersStatusBarHidden { return YES; }
A altura daEu estava usando o código de Peter Kreinz (porque estava limpo e fez o que eu precisava), mas então percebi que ele funciona exatamente quando o dispositivo está em retrato (pois o preenchimento superior estará no topo, obviamente). Então, criei uma extensão para lidar com todos os orientações com seus respectivos preenchimentos, sem retransmitir o tamanho da tela:
E no seu site de chamadas, você apenas:
fonte
Como alternativa, você pode conferir o pod ' DeviceKit '. Depois de instalado, tudo o que você precisa fazer para verificar o dispositivo é:
fonte
Nov 2019:
Aqui está o que eu uso em todos os meus projetos de produção. Note que esta essência é bastante longa.
Funciona com simuladores
Uso: deixe inserir: CGFloat = DeviceUtility.isIphoneXType? 50.0: 40.0
fonte
Eu tive que resolver o mesmo problema recentemente. E embora essa pergunta seja definitivamente respondida ("Não"), isso pode ajudar outras pessoas que precisam de um comportamento de layout específico do iPhone X.
Eu não estava realmente interessado em saber se o dispositivo era o iPhone X. Eu estava interessado em saber se o dispositivo tinha uma tela entalhada.
Você também pode escrever uma
hasOnScreenHomeIndicator
variável nas mesmas linhas (embora verifique a área inferior segura, talvez?).O exemplo acima usa minha extensão
UIView
para acesso conveniente às inserções da área segura no iOS 10 e versões anteriores.fonte
Em Retrato única Eu uso largura e altura do quadro do objectivo de verificar:
As dimensões da tela de retrato estão listadas aqui
fonte
Há vários motivos para querer saber qual é o dispositivo.
Você pode verificar a altura (e a largura) do dispositivo. Isso é útil para o layout, mas você geralmente não deseja fazer isso se quiser conhecer o dispositivo exato.
Para fins de layout, você também pode usar
UIView.safeAreaInsets
.Se você deseja exibir o nome do dispositivo, por exemplo, para ser incluído em um email para fins de diagnóstico, após recuperar o modelo do dispositivo
sysctl ()
, use o equivalente a isso para descobrir o nome:fonte