TextField с анимацией вылетает из приложения и теряет фокус - PullRequest
0 голосов
/ 23 февраля 2020

Минимальный воспроизводимый пример:

В SceneDelegate.swift:

let contentView = Container()

В ContentView.swift:

struct SwiftUIView: View {
    @State var text: String = ""

    var body: some View {
        VStack {
            CustomTextFieldView(text: $text)
        }
    }
}

struct Container: View {

    @State var bool: Bool = false
    @State var text: String = ""

    var body: some View {

        Button(action: {
            self.bool.toggle()
        }) {
            Text("Sheet!")
        }
        .sheet(isPresented: $bool) {
            SwiftUIView()
        }
    }
}

В CustomTextField.swift:

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false


    var body: some View {
        Group {
            if self.editing {
                textField
                    .background(Color.red)
            } else {
                ZStack(alignment: .leading) {
                    textField
                        .background(Color.green)
                    Text("Placeholder")
                }
            }
        }
        .onTapGesture {
            withAnimation {
                self.editing = true
            }
        }
    }

    var textField: some View {
        TextField("", text: $text)
    }

Проблема:

После запуска приведенного выше кода и фокусировки текстового поля приложение вылетает. Некоторые вещи, которые я заметил:

  1. Если я удаляю код withAnimation или файл ZStack в CustomTextField, приложение не обрабатывает sh, но TextField теряет фокус.
  2. Если я удаляю VStack в SwiftUIView, приложение не обрабатывает sh, но TextField теряет фокус.
  3. Если я использую NavigationLink или представляю TextField без лист, приложение не создает sh, но TextField теряет фокус.

Вопросы:

  • Это проблема в текущая версия SwiftUI?
  • Есть ли решение этой проблемы с помощью SwiftUI? Я хочу как можно дольше оставаться вне ViewRepresentables.
  • Как сохранить фокусировку TextField после пересчета тела из-за изменения состояния?

Ответы [ 2 ]

1 голос
/ 23 февраля 2020
  1. Как сохранить фокус TextField после пересчета тела из-за изменения состояния?

У вас их два. Два разных TextField не могут находиться в состоянии редактирования одновременно.

Подход, предложенный Аспери, является единственно возможным.

Причина, по которой ваш код взломал sh не легко объяснить, но ожидается в текущем SwiftUI.

Вы должны понимать, что Group - это не стандартный контейнер, это просто «блок», к которому вы можете применить некоторые модификаторы. При удалении группы и использовании переносящего тела во ViewBuilder

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false

    @ViewBuilder
    var body: some View {
            if self.editing {
                TextField("", text: $text)
                    .background(Color.red)
                    .onTapGesture {
                        self.editing.toggle()
                }
            } else {
                ZStack(alignment: .leading) {
                    TextField("", text: $text)
                        .background(Color.green)
                        .onTapGesture {
                                self.editing.toggle()
                        }
                }
        }

    }
}

код перестанет работать до sh, но есть и другая проблема, клавиатура немедленно исчезнет. Это из-за примененного жеста касания.

Так что, хотите верьте, хотите нет, вы должны использовать ТОЛЬКО ОДИН TextField.

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing = false

    var textField: some View {
        TextField("", text: $text, onEditingChanged: { edit in
            self.editing = edit
        })
    }

    var body: some View {

        textField.background(editing ? Color.green : Color.red)

    }
}

Используйте это настраиваемое текстовое поле в любом месте вашего кода, как вы хотите

0 голосов
/ 23 февраля 2020

Попробуйте следующее для CustomTextFieldView (протестировано и работает с Xcode 11.2 / iOS 13.2)

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false


    var body: some View {
        TextField("", text: $text)
            .background(self.editing ? Color.red : Color.green)
            .onTapGesture {
                withAnimation {
                    self.editing = true
                }
            }
    }
}

Как сохранить фокус TextField после пересчета тела, так как изменения в состоянии?

Вы не теряете фокус, вы просто удаляете текстовое поле целиком, поэтому решение состоит не в замене текстового поля, а в изменении его свойства, ie background. Это нормально, чтобы положить его в ZStack, но держите его один.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...