Quando o código funciona no simulador, mas quebra no dispositivo real: entendendo UI_USER_INTERFACE_IDIOM() em Swift
\n\nVocê já escreveu um aplicativo que fica perfeito no simulador do iPhone 14 Pro, mas no iPad Mini vira uma bagunça? Ou o contrário — sua interface moderna para iPad fica desalinhada em um iPod touch antigo? Uma dor familiar, certo?
\n\nDesenvolvedores iOS frequentemente enfrentam a necessidade de saber em qual dispositivo o aplicativo está sendo executado. Parece simples, não? Mas o diabo, como sempre, está nos detalhes. A lendária pergunta no Stack Overflow sobre UI_USER_INTERFACE_IDIOM() acumulou milhares de visualizações, o que significa que até programadores experientes às vezes se confundem com as nuances.
Neste artigo, vamos detalhar tudo o que você precisa saber sobre a determinação do dispositivo em Swift. Sem enrolação — apenas prática, exemplos reais e respostas para as perguntas mais frequentes.
\n\nO que é UI_USER_INTERFACE_IDIOM() e por que falam tanto sobre ele?
\n\nÉ uma boa e velha função da era do Objective-C. Ela retorna um valor do tipo UIUserInterfaceIdiom, que indica com qual tipo de dispositivo estamos lidando: iPhone, iPad, TV ou CarPlay.
Veja como era no Objective-C clássico:
\n\nif (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {\n // Isto é um iPad\n} else {\n // Isto é um iPhone ou iPod touch\n}\n\nMas Swift é uma linguagem mais rigorosa e segura. O uso direto dessa função em C nem sempre é conveniente. Surgiu uma abordagem mais moderna através de UIDevice.current.
Como determinar corretamente o dispositivo em Swift: duas formas funcionais
\n\nMétodo nº 1 — clássico via UIDevice (recomendado):
import UIKit\n\nlet deviceIdiom = UIDevice.current.userInterfaceIdiom\n\nswitch deviceIdiom {\ncase .phone:\n print("Isto é um iPhone ou iPod touch")\ncase .pad:\n print("Isto é um iPad")\ncase .tv:\n print("Isto é um Apple TV")\ncase .carPlay:\n print("Isto é CarPlay")\ncase .mac:\n print("Isto é Mac Catalyst ou Mac")\n@unknown default:\n print("Dispositivo desconhecido (possivelmente futuro)")\n}\n\nImportante: O caso .mac surgiu no iOS 14+. Se seu aplicativo suporta versões mais antigas, use @unknown default para lidar com tipos futuros.
Método nº 2 — compatibilidade com código Objective-C (se necessário):
\n\nif UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.phone {\n print("Trabalhando no telefone")\n}\n\nAmbas as opções são corretas, mas a primeira é mais idiomática para Swift.
\n\nPerguntas frequentes e armadilhas
\n\n1. Por que no iPad mini é detectado como iPhone?
\n\nEsta é a pergunta mais popular. Você executa o aplicativo em um iPad mini, mas userInterfaceIdiom insiste em retornar .phone. Qual é o problema?
A resposta é simples e não óbvia: Modo de Escala (Scale Mode). Se nas configurações do seu aplicativo (Target → General → Deployment Info) o modo "iPhone" estiver selecionado, mesmo em um iPad físico o sistema emulará um iPhone.
\n\nSolução: verifique as configurações do projeto.
\n- \n
- Vá em Target do seu aplicativo \n
- General → Deployment Info \n
- Devices: selecione "Universal" (se o aplicativo deve funcionar em todos os dispositivos) \n
Se você escolheu "iPhone Only", no iPad o aplicativo funcionará em modo de compatibilidade (como em um iPhone grande), e o idiom será .phone.
2. Como diferenciar iPhone de iPod touch?
\n\nUI_USER_INTERFACE_IDIOM() não diferencia iPhone de iPod touch — ambos retornam .phone. Para determinar o modelo exato, use UIDevice.current.model ou modelName via sysctl.
Exemplo de extensão para obter o nome exato do modelo:
\n\nimport UIKit\n\nextension UIDevice {\