Resizability no iOS: quando seu app deixa de saber em qual dispositivo roda

Cinco princípios de design, cada um aterrissado em código: na era do redimensionamento, um app só se pergunta quanto espaço tem. Com configuração de cena, callbacks de geometria, estratégia de duas passadas, linhas vermelhas do Info.plist e matriz de teste.

A resizability é a capacidade da janela de um app de ser pega pela borda e arrastada livremente para qualquer tamanho, como uma janela de desktop. O pensamento de design que a Apple acompanha essa mudança cabe em uma frase: um app não se preocupa mais em saber em qual dispositivo roda, em qual orientação, em qual tela. Só lhe importa quanto espaço tem neste instante. Você define dois comportamentos: como o conteúdo se organiza quando há mais espaço e como quando há menos. O sistema aplica essa lógica em todos os dispositivos, todos os tamanhos de janela e todas as posturas de dobradiça.

Isso não é uma atualização de API corriqueira. É uma troca de faixa no paradigma de layout desde o nascimento do iOS. Este artigo decompõe o pensamento de design em cinco princípios, faz cada um aterrissar em código UIKit e SwiftUI, e termina com um roteiro de migração e uma matriz de teste que você pode executar do jeito que está.

As assinaturas no texto foram conferidas com o SDK do iOS 27.1 no Xcode 27.1. O comportamento segue a documentação da Apple e as sessões da WWDC, cujas fontes estão listadas no final. O corpo é uma reexposição e uma organização técnica, não uma tradução de uma página específica.

1. Do iOS 26 ao 27: como o redimensionamento virou o padrão

Antes do pensamento de design, a linha do tempo. Ela explica por que o jeito antigo de fazer já não basta.

Etapa O que aconteceu O que significa para você
iPadOS 15 Split View / Slide Over / Stage Manager O iPad passa a ter tamanhos fora da tela cheia
iPadOS 26 O iPad entra na era das janelas livres A suposição «iPad = regular» começa a balançar
SDK do iOS 26 UIRequiresFullScreen fica obsoleto Não dá mais para sair do redimensionamento pelo botão de tela cheia
SDK do iOS 26 Apps de iPhone também redimensionam no iPad e no espelhamento no Mac «Rodar num iPhone» já não significa compact
iOS 27 O ciclo de vida UIScene é obrigatório para builds com SDK recente As cenas passam a ser a base
iOS 27 Barra de abas, barras de ferramentas: os componentes do sistema se adaptam a qualquer proporção Os componentes do sistema fazem o trabalho pesado

O fio em uma frase: o tamanho da janela passou de valor enumerado para valor contínuo. Antes seu app encarava 375, 393, 414, 768, 1024. Agora um dedo pega a borda da janela e arrasta uma vez: a largura pode ser qualquer número entre 320 e o limite da tela. Um layout escrito para degraus discretos quebra com certeza diante de um valor contínuo.

2. Princípio um: do «pensamento de dispositivo» ao «pensamento de espaço»

A maior parte do conhecimento antigo de layout repousa sobre o pensamento de dispositivo: isto é um iPhone, está em paisagem, então dispõe-se assim; isto é um iPad, então divide-se em dois. A resizability pede para trocar esse pensamento por completo.

Pensamento de dispositivo (velho) Pensamento de espaço (novo)
Critério de decisão Tipo de dispositivo, orientação, tamanho de tela Espaço disponível do contêiner atual
Quantidade de layouts Uma versão por dispositivo Um único conjunto de regras para todos os espaços
Hardware novo Pode exigir mudança de código e uma entrega Aplica-se sozinho, zero mudanças
Posturas de dobradiça Uma interface a mais por postura Uma interface que se alonga com a largura
Sinal de alerta no código if idiom == .pad, isLandscape horizontalSizeClass, largura do contêiner

A formulação mais crua do pensamento de espaço vem da WWDC: você não desenha para cada plataforma nem para cada tamanho de janela. Você define uma vez como o conteúdo se comporta quando há mais lugar e quando há menos. O sistema aplica essa lógica em todas as proporções. Girar a tela é apenas um disparador dessa lógica, da mesma natureza que arrastar uma janela, entrar em Split View ou desdobrar uma tela: tudo conflui para o mesmo ponto único: o espaço disponível mudou.

3. Princípio dois: as classes de tamanho são a nova língua franca

Quando o pensamento de dispositivo se retira, quem assume o bastão? A classe de tamanho. É o julgamento qualitativo que o framework faz do espaço: dois eixos, duas palavras por eixo: compact significa apertado, regular significa folgado.

  • O eixo horizontal julga esquerda e direita: em compact, o conteúdo deve empilhar em uma coluna; só em regular as colunas, o pareamento e a barra lateral ficam honestos.

  • O eixo vertical julga acima e abaixo: em compact, o chrome vertical (barra de abas, barra de ferramentas) não cabe mais, e o sistema levanta uma barra de abas horizontal na vertical. Em regular, as barras de cima e de baixo coexistem.

Em SwiftUI a leitura é direta:

@Environment(\.horizontalSizeClass) private var hSize  // UserInterfaceSizeClass?
@Environment(\.verticalSizeClass) private var vSize

if hSize == .regular {
    // Lugar à esquerda e à direita: colunas / barra lateral / duas fileiras
} else {
    // Apertado à esquerda e à direita: uma coluna empilhada
}

Em UIKit, traitCollection.horizontalSizeClass carrega o mesmo dever, e com registerForTraitChanges é possível assinar as mudanças com precisão.

Vem agora a tabela mais importante deste artigo: as classes de tamanho não estão em correspondência biunívoca com o dispositivo nem com a orientação:

Cena Horizontal Vertical Nota
iPhone retrato compact regular A forma padrão de todo o app
iPhone paisagem compact compact Só uns 320 pt de altura, a barra passa para a vertical
Janela do iPhone ampliada (iOS 26+) regular regular Muda em tempo de execução, não no lançamento
iPad tela cheia regular regular Cerca de 1024 pt de largura
iPad em Split View pela metade regular regular Só uns 507 pt de largura, ainda regular
iPad em Slide Over compact compact Uma forma compact no iPad
Tela externa do Duo compact compact Cerca de 466 pt de largura
Tela interna do Duo desdobrada regular compact Muda em tempo de execução com a dobradiça

Leia esta tabela três vezes e duas conclusões contra-intuitivas emergem: «rodar num iPhone» já não significa compact (uma janela ampliada é regular), e «rodar num iPad» já não significa regular (Slide Over é compact). Nem o tipo de dispositivo nem a orientação respondem «que layout devo usar agora». É preciso perguntar à classe de tamanho, em tempo de execução.

A tabela também corrige uma crença antiga: girar o dispositivo não significa «o dispositivo mudou». Girar comuta o par (H, V) de (compact, regular) para (compact, compact) e muda os limites uma vez. A estrutura do seu código de layout não se move; o que se move é a entrada. Na época em que a orientação era um conceito de layout, ela sempre foi uma variável de substituição. A substituição acabou. Só resta o espaço.

O penhasco das classes de tamanho: por que ainda precisa de uma segunda passada

As classes de tamanho são binárias, e grossas o bastante para «mentir». Veja o penhasco: o iPad em tela cheia com 1024 pt e a metade em Split View com 507 pt são ambos (regular, regular): mas um cabe uma barra lateral, o outro não. Duas palavras não conseguem responder às perguntas de grau: quantas colunas, de que tamanho, limitar a largura ou não.

O modo maduro é, portanto, um revezamento de duas passadas: as classes de tamanho respondem à pergunta de direção (uma coluna ou dividido), a estratégia de engenharia responde à pergunta de grau (quantas colunas, tamanho do herói, largura de leitura). A segunda passada costuma escalonar pela largura medida do contêiner: em tela larga, limita o texto a um comprimento de linha confortável, ou deduz o número de colunas do tamanho mínimo do conteúdo. Desde o iOS 17, o SwiftUI consegue medir direto o tamanho do contêiner com onGeometryChange e injetá-lo na decisão: não precisa recorrer ao GeometryReader.

4. Princípio três: a funcionalidade não muda com o tamanho, muda apenas a quantidade visível

Este é um princípio das Human Interface Guidelines fácil de deixar passar e impossível de superestimar: quando a classe de tamanho muda, o conjunto de funcionalidades permanece idêntico. O que muda é «quanto se vê de uma vez».

Em uma tela larga, a barra de abas se desdobra em barra lateral e revela destinos de segundo nível. Em uma janela estreita, as ferramentas de baixa prioridade vão para o menu de excesso e continuam a um toque. Esconder é rearranjar, não apagar. Se uma ação existe no layout largo e desaparece sem rastro no estreito, isso não é adaptação, é funcionalidade ausente. Da mesma forma, entre retrato e paisagem nunca deve existir «esta tela só opera completamente em uma orientação»: o que funciona em retrato tem de funcionar de ponta a ponta em paisagem.

A exigência implícita para quem desenha o produto: na arquitetura da informação, escreva uma prioridade para cada elemento. Compartilhar e ações principais têm prioridade alta e residem em qualquer tamanho. Salvar e ajustes secundários têm prioridade baixa: residem no largo, vão para o excesso no estreito. O mecanismo Visibility Priority dos componentes do sistema faz exatamente isso.

5. Princípio quatro: os tamanhos min / max previnem sobreposição, não recusam o redimensionamento

O UIKit permite que uma cena declare um tamanho mínimo e um máximo. Mas a semântica precisa ficar clara: esses dois valores existem para evitar que elementos se cubram uns aos outros em tamanhos pequenos e se desmanchem em tamanhos grandes. Eles não são uma barreira que o usuário precisa superar antes de ter permissão para arrastar. A partir do momento em que uma janela pode ser arrastada para qualquer tamanho, sua responsabilidade é manter o conteúdo utilizável, legível e sem sobreposições em qualquer tamanho. Se um tamanho específico quebra inevitavelmente, então seu tamanho mínimo foi ganancioso demais, ou o layout ainda não é realmente adaptativo.

Declara-se na conexão da cena:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
           options: UIScene.ConnectionOptions) {
    guard let windowScene = scene as? UIWindowScene else { return }

    // Limite inferior: abaixo dele, os elementos começam a se sobrepor.
    // Limite superior: acima dele, o layout afrouxa.
    windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
}

A dívida antiga que acompanha: UIRequiresFullScreen está obsoleto, e quem o mantém fica excluído do redimensionamento: abandona automaticamente os novos tamanhos de tela. Desde o SDK do iOS 26, os apps não precisam nem mudar código nem reenviar para telas novas; o sistema se adapta sozinho, desde que você não tranque a porta por conta própria.

6. Princípio cinco: deixe os componentes do sistema fazerem o trabalho

A estratégia menos custosa na era da resizability é entregar o rearranjo aos componentes do sistema. O trato deles com proporções arbitrárias é mais robusto que qualquer layout escrito à mão:

  • Barras de abas e barras de ferramentas: quando a janela se alarga, os ícones das abas ficam na mesma linha que seus rótulos e mantêm a barra compacta; quando se estreita, as ferramentas de baixa prioridade escorrem para o menu de excesso. Num app de notícias, «Compartilhar» pode ser fixado em qualquer tamanho e «Salvar para depois» só transborda no estreito: declarado por Visibility Priority, sem uma linha de código de layout.

  • Barras laterais: desde o iPadOS 26, os apps de iPhone também podem escolher um layout com barra lateral quando o espaço permite, protegido por sidebar.isAvailable.

  • NavigationSplitView: desde o iOS 26, as colunas aparecem e desaparecem conforme o espaço; gerenciar a visibilidade delas à mão não é mais necessário.

  • Materiais de sistema Liquid Glass: no iOS 27, com difusão melhorada e separação de bordas; herdados sem recompilar.

Sua própria interface tem aqui exatamente uma tarefa: não brigar com esses tijolos. As barras de topo desenhadas à mão precisam evitar os controles de fechar e minimizar no canto superior esquerdo da janela (pelo guia de layout com adaptação horizontal de cantos). Nunca suponha que a barra de abas está sempre embaixo nem a barra de ferramentas sempre em cima: a própria forma delas muda com o espaço.

7. UIKit na prática: configuração de cena e resposta à geometria

As cenas são a base da resizability: cada cena gerencia de forma independente sua própria instância de interface e estado, e fornece o contexto «onde e a que tamanho está esta interface». Desde o iOS 27, os builds com SDK recente precisam adotar o ciclo de vida UIScene: não é opcional.

Uma armação de delegado de cena para copiar tal e qual:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
               options: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }

        // 1) Declarar capacidades de tamanho: prevenir sobreposição, não recusar redimensionamento
        windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)

        // 2) Pendurar a janela na cena; nunca UIWindow(frame: UIScreen.main.bounds)
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = AdaptiveRootController()
        self.window = window
        window.makeKeyAndVisible()
    }

    // 3) Callback de mudança de geometria: arrastar, Split View, desdobrar, tela externa
    func windowScene(_ windowScene: UIWindowScene,
                     didUpdateEffectiveGeometry previous: UIWindowScene.Geometry) {
        let geometry = windowScene.effectiveGeometry
        let size = geometry.coordinateSpace.bounds.size

        // isInteractivelyResizing significa que o usuário ainda segura a borda.
        // O trabalho pesado (reconstrução de recursos, recálculo de gráficos)
        // acontece uma vez, quando o gesto termina: não para cada tamanho intermediário.
        if !geometry.isInteractivelyResizing,
           size != previous.coordinateSpace.bounds.size {
            AssetStore.shared.rebuild(for: size)
        }
    }

    // 4) Preferência de estilo dos controles de janela (fechar / minimizar), iPadOS 26+
    func preferredWindowingControlStyle(for scene: UIWindowScene)
        -> UIWindowScene.WindowingControlStyle {
        .unified
    }
}

Três pontos merecem desdobramento:

isInteractivelyResizing é a tábua de salvação do desempenho ao arrastar. Enquanto o usuário arrasta, o sistema reporta a geometria continuamente. Se um jogo ou app reconstrói os recursos de renderização para cada tamanho intermediário, a taxa de quadros despenca no ato. A postura padrão: enquanto arrasta, só o leve (restrições, tamanhos de fonte); ao soltar, uma vez o pesado.

Nunca pegue a tela e o tamanho via UIScreen.main. No espelhamento e em tela externa, a tela principal é a resposta errada. As fontes corretas são view.window?.windowScene?.screen, a effectiveGeometry da cena, ou os view.bounds locais da view.

Evitar os controles de janela. Desde o iPadOS 26, o canto superior esquerdo da cena carrega os controles de fechar e minimizar. As barras de topo desenhadas à mão precisam se ligar a containerView.layoutGuide(for: .margins(cornerAdaptation: .horizontal)), ou seu primeiro botão fica intocável.

8. A camada das views: riscar três modos antigos

O código UIKit adaptativo é, no fundo, «três substituições»:

Riscar Substituir por Por quê
UIScreen.main.bounds view.bounds / effectiveGeometry / windowScene?.screen Em Split View e espelhamento, a tela principal não é sua janela
Os ramos userInterfaceIdiom == .pad traitCollection.horizontalSizeClass O tipo de dispositivo não carrega semântica de layout
Os ramos interfaceOrientation Classe de tamanho + limites locais A orientação é um resultado do layout, não sua causa

Depois da troca, a mudança de trait pilota o layout:

class AdaptiveRootController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Rearranjar na mudança de classe de tamanho; o registro cobre também
        // a invalidação de cache que o rastreamento automático não vê
        registerForTraitChanges([UITraitHorizontalSizeClass.self,
                                 UITraitVerticalSizeClass.self]) { (vc: Self, _) in
            vc.applyLayout()
        }
    }

    private func applyLayout() {
        switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
        case (.regular, _):   useSidebarLayout()
        case (.compact, _):   useStackedLayout()
        default:              useStackedLayout()
        }
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // Quando o julgamento é mais fino que uma classe de tamanho: tamanho local disponível
        fineTune(for: view.bounds.size)
    }
}

Note que viewDidLayoutSubviews / layoutSubviews agem de forma contínua: a mudança de classe de tamanho dispara o «rearranjo estrutural», a mudança de limites dispara o «ajuste fino». Ler o tamanho uma única vez em onAppear / viewDidLoad e guardar produz os primeiros valores velhos assim que o redimensionamento começa.

9. SwiftUI na prática: em grande medida automático, reforçado nos pontos-chave

Os apps escritos em SwiftUI saem na frente na resizability: recompilados com o Xcode 27, o suporte a redimensionamento chega sozinho, não há API nova para adotar, e os novos materiais Liquid Glass são herdados de graça. Mas «automático» não quer dizer «sem inspeção». A caixa de ferramentas do lado SwiftUI:

  • @Environment(\.horizontalSizeClass) / verticalSizeClass: o equivalente do trait UIKit, responde às perguntas de direção.

  • onGeometryChange(for:of:action:): mede o contêiner, responde às perguntas de grau. Ele lê sem disparar a ocupação gulosa de espaço do GeometryReader, e só chama a action quando o valor derivado muda de verdade: um filtro natural para os tamanhos intermediários do arrasto.

  • ViewThatFits: o declarativo «pega o primeiro que caiba», indicado quando o conteúdo troca de disposição conforme a largura.

  • containerRelativeFrame(): dimensiona pela proporção do contêiner em vez de pontos absolutos; especialmente útil para zonas que precisam se estender sob a interface do sistema.

  • NavigationSplitView: desde o iOS 26, a largura e a visibilidade das colunas se adaptam sozinhas; não embrulhe por cima uma gestão manual de colunas.

  • .windowResizability(.contentMinSize): a entrada do SwiftUI para declarar o tamanho mínimo da cena, a contraparte de sizeRestrictions?.minimumSize.

Um revezamento de duas passadas típico:

struct DashboardView: View {
    @Environment(\.horizontalSizeClass) private var hSize
    @State private var columnCount = 1

    var body: some View {
        ScrollView {
            MetricGrid(columns: columnCount)
        }
        // Passada um: a classe de tamanho decide uma coluna ou dividido
        .onChange(of: hSize) { _, new in
            usesSidebar = (new == .regular)
        }
        // Passada dois: a largura medida decide o número de colunas,
        // cobrindo 507 e 1024 que ambos são "regular"
        .onGeometryChange(for: CGFloat.self) { $0.size.width } action: { _, width in
            columnCount = AdaptiveWindowLayoutPolicy.tier(for: width).columns
        }
    }
}

10. Linhas vermelhas no Info.plist e no Launch Screen

Duas linhas vermelhas vivem na configuração do projeto. Erre uma e ela detona no momento do envio:

  1. UIRequiresFullScreen precisa ser tratado. Obsoleto, e quem o mantém fica excluído do redimensionamento. Apague; se ele carrega uma necessidade real de compatibilidade com o passado, use UIRequiresFullScreenIgnoredStartingWithVersion para declarar a partir de qual versão a chave é ignorada. Os jogos entram por isso no redimensionamento discreto: depois de cada arrasto concluído, comutam para uma nova configuração de tela combinada com o tamanho, o que preserva a renderização em qualidade total.

  2. O Launch Screen é obrigatório. Desde o SDK do iOS 27, um app sem Launch Screen configurado não passa no envio para a App Store (TN3208). Num projeto SwiftUI, isso em geral significa acrescentar uma configuração mínima de tela de lançamento: não continuar correndo descalço.

11. Referência rápida de antipadrões

Antes de tocar no código, passe a base de código pela peneira desses padrões. Cada ocorrência é uma dívida a pagar:

Antipadrão Por que quebra Substituir por
UIScreen.main.bounds Em Split View / espelhamento, não é sua janela view.bounds locais ou geometria da cena
Os ramos UIDevice.current.userInterfaceIdiom O tipo de dispositivo não tem semântica de layout horizontalSizeClass
interfaceOrientation / notificações de orientação Reportam a postura do dispositivo, não a forma da janela Classe de tamanho + limites locais
Limiares caseiros tipo size.width > 600 Contornam a semântica de traits, falham os estados intermediários do Split View Estratégia de escalonamento de engenharia + onGeometryChange
Ler o tamanho uma vez em onAppear O redimensionamento é contínuo; o cache envelhece na hora Callbacks de trait / geometria
Layout largo só para o iPad Um iPad em Slide Over se comporta como um telefone Lógica larga e lógica estreita ambas disparadas pelo espaço
.frame(height: 480) fixo para mapas / heróis Em janelas curtas, o texto escorrega para fora da primeira tela Altura relativa ao contêiner ou adaptativa

12. Roteiro de migração

Quatro passos, ordenados por risco e retorno:

Fase 1 · Desarmar (primeiro, bloqueia o envio): apagar UIRequiresFullScreen, acrescentar o Launch Screen, confirmar que o ciclo de vida UIScene está em uso. Esses três pontos são portas duras, sem relação com a qualidade do design; errar um trava direto no build ou na revisão.

Fase 2 · Limpar antipadrões: com a tabela da seção 11, substituir em toda a base UIScreen.main, os ramos idiom / orientação e os limites de largura caseiros. O objetivo não é «roda»: é unificar a entrada do layout sobre a semântica do espaço.

Fase 3 · Construir as duas passadas: para as telas conduzidas pelo conteúdo, estabelecer a estratégia «a classe de tamanho decide a direção + a largura medida decide o grau», e fazer convergir cada limite nu para esse lugar único. Em tela larga, limitar a largura do texto: uma linha com mais de 85 caracteres é um bug de legibilidade.

Fase 4 · Sistematizar os testes: percorrer a matriz da seção 13 tamanho por tamanho, e congelar os resultados como pontos de não regressão.

13. Matriz de teste

Os testes de resizability não se organizam por listas de dispositivos, mas por formas de espaço. Cada forma precisa responder: a funcionalidade está completa, o conteúdo está cortado, o chrome é tocável?

Forma de espaço O que verificar
Largura utilizável mais estreita (perto de minimumSize) Sobreposição de elementos, botões principais tocáveis
Largura de telefone padrão Linha de base do layout padrão
Telefone em paisagem Em vertical compact: barra de abas na vertical, primeira tela completa
Janela de telefone ampliada até regular As colunas assumem o lugar, o estado se conserva
Split View pela metade / Slide Over Dois comportamentos de espaço no mesmo iPad
Proporções extremas larga-achatada e alta-estreita A extensão do fundo aguenta, o conteúdo não se rasga
Duo externo e interno desdobrada Layout e estado contínuos ao virar a dobradiça
Espelhamento de iPhone / tela externa As consultas de tela e tamanho estão corretas

Do lado das ferramentas, o Device Hub e as Previews do Xcode 27 oferecem um modo de redimensionamento de janela; puxar a borda muda o tamanho de forma contínua. Espelhamento e telas externas se verificam em hardware real.

14. Perguntas frequentes

Por que meu app de iPhone de repente pode ser arrastado para uma janela maior?

Não é bug: comportamento novo desde o SDK do iOS 26. Os apps de iPhone que rodam no iPad e no espelhamento de iPhone no Mac têm janelas livremente redimensionáveis. O sinal de layout correspondente é a classe de tamanho horizontal comutando de compact para regular. O velho código if idiom == .phone produz o layout errado em tais janelas: pergunte à classe de tamanho.

As classes de tamanho bastam? Por que medir a largura também?

Não bastam, e o penhasco é real. O iPad em tela cheia e a metade em Split View são ambos (regular, regular), mas as larguras diferem por um fator de dois: um cabe uma barra lateral, o outro não. As classes de tamanho decidem a direção (uma coluna ou dividido), a largura medida decide o grau (quantas colunas, de que tamanho). As duas são um revezamento, não uma escolha.

Se eu declarar minimumSize, os usuários não podem mais arrastar para menor?

minimumSize é o limite abaixo do qual seu conteúdo começaria a se embaraçar; os usuários não conseguem arrastar além dele. É um mecanismo de prevenção de sobreposição, não um portal de funcionalidade contra o redimensionamento. O que você deve é usabilidade em qualquer tamanho entre minimumSize e maximumSize. Se um tamanho falha, a adaptação está inacabada: não é razão para aumentar o mínimo.

O que acontece se eu apagar UIRequiresFullScreen?

O app entra no redimensionamento de janelas, o esperado por padrão desde o iOS 26+. Para compatibilidade com o passado, você pode usar UIRequiresFullScreenIgnoredStartingWithVersion para declarar a versão a partir da qual ignorar; os jogos entram em redimensionamento discreto e comutam depois de cada arrasto para uma configuração de tela combinada, o que preserva melhor a qualidade de renderização.

O que um app SwiftUI realmente precisa fazer?

Recompilar, e o suporte a redimensionamento já está; não há API nova para adotar. Inspecione em vez disso: código que se apoia em suposições da era do UIScreen; julgamentos de tamanho que só usam classes de tamanho sem reforço de medição; componentes de frame fixo que se rasgam nas proporções extremas. O framework cuida do macro. O componente que se rasga costuma ser aquele que você mesmo pregou.

Fontes e leitura complementar

Fontes oficiais: a sessão WWDC25 282 «Make your UIKit app more flexible», a sessão WWDC26 278 «Modernize your UIKit app», as seções Layout e Designing for iPhone Duo das Human Interface Guidelines, a documentação de UISceneSizeRestrictions e UIWindowScene.Geometry, e as notas técnicas TN3192: migração da chave UIRequiresFullScreen obsoleta e TN3208: requisitos do Launch Screen.

Leitura complementar neste site: para ver o mesmo pensamento aterrissar de ponta a ponta num dispositivo concreto, leia Criar para o iPhone Duo, do layout ao código. Para a outra face: os dados também precisam se contrair com o espaço, veja o guia da linha de base pessoal. As demais perguntas de produto e adaptação estão nas perguntas frequentes.

Continue lendo

Experimente essas ideias no Stress HRV

Baixar na App Store

Estas notas compartilham pensamento de produto para bem-estar. Não são conselho médico.