Анимация не применяется к изменению состояния представления SwiftUI - PullRequest
1 голос
/ 26 февраля 2020

Я пытаюсь анимировать изменение наложения, примененного к SwiftUI TextField. Состояние наложения контролируется переменной состояния (простой логический тип), и большинство ссылок предполагает, что добавление .animation () к привязке этой переменной в элементе управления Toggle должно помочь. Однако, это, кажется, не имеет никакого эффекта. Я попытался добавить тот же модификатор к представлению, используемому для наложения, и обернуть компонентные представления для наложения в блоках анимации - опять же, без радости.

Интересно, что я заметил ошибку при запуске кода либо в холст или симулятор, который может быть значимым:

2020-02-25 22:00:19.360009+0000 Sandbox[9392:671490] invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.

Код выглядит следующим образом (его прототипирование довольно грубое и готово). Может кто-нибудь сказать мне, что мне не хватает?

import SwiftUI

struct ContentView: View {
    @State private var isValid = true

    var body: some View {
        VStack {
            Form {
                TextField("Placeholder", text: .constant(""))
                    .padding(6)
                    .background(ErrorView(isValid: $isValid)
                    .overlay(RoundedRectangle(cornerRadius: 4)
                            .stroke(Color(.systemGray3), lineWidth: 1))
                    .padding()

                Toggle(isOn: $isValid.animation(.easeInOut), label: { Text("Toggle Valid") })
            }
        }
    }
}

struct ErrorView: View {
    @Binding var isValid: Bool

    var body: some View {
        if isValid {
            return AnyView(EmptyView())
        } else {
            return AnyView(
                ZStack {
                    HStack {
                        Spacer()
                        Image(systemName: "exclamationmark.triangle.fill")
                            .foregroundColor(Color.red)
                            .padding(.trailing, 8)
                    }

                    HStack {
                        Spacer()
                        Text("error message")
                            .font(.caption)
                            .foregroundColor(Color.red)
                            .offset(x: 0, y: -28)
                    }
                }
            )
        }
    }
}

1 Ответ

1 голос
/ 26 февраля 2020

Здесь возможен и немного упрощен подход (протестировано и работает с Xcode 11.2 / iOS 13.2)

demo

struct ContentView: View {
    @State private var isValid = true

    var body: some View {
        VStack {
            Form {
                TextField("Placeholder", text: .constant(""))
                    .padding(6)
                    .background(ErrorView().opacity(isValid ? 0.0 : 1.0))
                    .overlay(RoundedRectangle(cornerRadius: 4)
                            .stroke(Color(.systemGray3), lineWidth: 1))
                    .padding()

                Toggle(isOn: $isValid.animation(), label: { Text("Toggle Valid") })
            }
        }
    }
}

struct ErrorView: View {

    var body: some View {
        ZStack {
            HStack {
                Spacer()
                Image(systemName: "exclamationmark.triangle.fill")
                    .foregroundColor(Color.red)
                    .padding(.trailing, 8)
            }

            HStack {
                Spacer()
                Text("error message")
                    .font(.caption)
                    .foregroundColor(Color.red)
                    .offset(x: 0, y: -28)
            }
        }
    }
}
...