SwiftUI em iOS14 Keyboard Avoidance Issues e IgnoresSafeArea Modifier Issues

Sep 19 2020

iOS13 viu que o TextField não tinha nenhum tipo de manipulação de teclado para evitar. Como tal, criamos nosso mecanismo de como evitar teclado que funciona bem. Atualizamos para o iOS14 e isso resultou em TextFields com proteção de teclado incorporada. No entanto, a proteção de teclado não parece funcionar como esperado.

Problema 1 O primeiro problema que enfrentamos foi evitar que o teclado funcionasse como esperado para TextFields no centro e ao redor da tela. Dado este código:

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {
        
        TextField("Testing", text: $text)

    }
}

Em um e no iPhone 8 Plus, o campo de texto é movido para cima. Em nossa opinião, isso não deveria estar acontecendo, pois o TextField não ficará oculto pelo teclado e, como tal, deve permanecer no mesmo lugar.

Pergunta 1: Isso é um bug e deve ser relatado à Apple? Acreditamos que isso seja um bug / problema.

Descobrimos isso usando o seguinte:

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {
        
        VStack {
            Spacer()
            TextField("Testing", text: $text)
        }
        
    }
}

O TextField será movido logo acima do teclado. Qual é o comportamento esperado. Também descobrimos isso com o código abaixo:

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {
        
        VStack {
            TextField("Testing", text: $text)
            Spacer()
        }
        
    }
}

O TextField não é movido, pois nunca seria coberto pelo TextField. Mais uma vez, esse é o comportamento que esperamos. No entanto, qualquer TextField dentro e ao redor do centro da tela, pareceria que a evitação do teclado move o TextField em cenários onde não deveria.

Problema 2 Nosso aplicativo mantém TextFields dentro e ao redor do centro em certas telas e, como tal, o problema descoberto acima simplesmente contribui para uma experiência do usuário ruim e, portanto, procuramos "desligar" esta proteção de teclado fornecida para nós. Procuramos usar o ignoresSafeAreamodificador da seguinte maneira:

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {

        if #available(iOS 14.0, *) {
            
            VStack {
                TextField("Testing", text: $text)
            }
            .ignoresSafeArea(.keyboard, edges: .bottom)

            
        } else {
            // Fallback on earlier versions
            // Our iOS13 Code
        }
                
    }
}

O resultado observado é que o modificador simplesmente não funciona. O TextField ainda é movido para cima. No entanto, ao usar algo assim:

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {

        if #available(iOS 14.0, *) {
            
            VStack {
                Spacer()
                TextField("Testing", text: $text)
            }
            .ignoresSafeArea(.keyboard, edges: .bottom)

            
        } else {
            // Fallback on earlier versions
            // Our iOS13 Code
        }
                
    }
}

as ignoresSafeAreaobras e isso leva à segunda questão:

Questão 2 : também há bug com o ignoresSafeAreamodificador? Isso é algo que deve ser relatado?

Parece que há um problema subjacente com TextFields no centro e ao redor da tela?

Pergunta 3 Alguém conhece maneiras de contornar esses problemas? Porque agora é um grande problema no iOS14. A evitação do teclado não funciona e qualquer tentativa de desligá-lo também não funciona.

Estamos usando o Xcode 12.0 (12A7209)

Atualizar

Descobrimos que envolver o TextField em um leitor de geometria parece "desligar" o teclado evitado para um TextField. No entanto, acreditamos que este seja um hack delicioso que corrige o problema de uma maneira, mas também expõe que o Keyboard Avoidance não funciona em leitores de geometria, o que pode ser um bug / problema para outras pessoas ...

struct ContentView: View {
    
    @State var text:String = ""
    
    var body: some View {

        if #available(iOS 14.0, *) {
            
            GeometryReader { _ in
                VStack {
                    Spacer().frame(height:500) //Compensate for other Views in the Stack
                    TextField("Testing", text: $text)
                }
            }
            
        } else {
            // Fallback on earlier versions
            // Our iOS13 Code
        }
                
    }
}

Respostas

los.adrian Sep 20 2020 at 01:25

Aqui você pode ver o que descobri com base em seu hack GeometryReader: https://stackoverflow.com/a/63971318/2645599