Как добавить анимацию на изменения высоты Spacer в scrollview в SwiftUI? - PullRequest
0 голосов
/ 30 января 2020

У меня есть KeyboardObserver, который наблюдает за изменениями на клавиатуре и вычисляет необходимую высоту, чтобы настроить вид следующим образом:

final class KeyboardObserver: ObservableObject {

    public var lastViewRect = CGRect()

    @Published  var keyboardMinY: CGFloat = 0 {
        didSet {
            if keyboardMinY == 0 {
                lastViewAdjustment = 0
            } else {
                lastViewAdjustment = keyboardMinY - lastViewRect.maxY
            }
        }
    }
    @Published  var lastViewAdjustment: CGFloat = 0

    // keyboardWillShow notification may be posted repeatedly,
    // this flag makes sure we only act once per keyboard appearance
    @Published var keyboardIsHidden = true

    func addObserver() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardDidHide(notification:)), name: UIResponder.keyboardDidHideNotification, object: nil)
    }

    func removeObserver() {
        NotificationCenter.default.removeObserver(self)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc func keyBoardWillShow(notification: Notification) {
        if keyboardIsHidden {
            keyboardIsHidden = false
            if let rect = notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect {
                keyboardMinY = rect.minY
            }
        }
    }

    @objc func keyBoardDidHide(notification: Notification) {
        keyboardIsHidden = true
        keyboardMinY = 0
    }
}

Я использую его в представлении следующим образом:

struct SignUpView: View {

    @ObservedObject private var keyboardObserver = KeyboardObserver()

    var body: some View {
        VStack(alignment: .leading) {

            ...

            ScrollView {
                IndicatorTextField("Full Name", .imageUserBlue, .turquoiseBlue)
                    .padding(.top, 48)

                IndicatorTextField("Email Address", .imageEmail, .turquoiseBlue)
                    .padding(.top, 8)

                IndicatorTextField("Home Town", .imageLocation, .turquoiseBlue)
                    .padding(.top, 8)

                IndicatorTextField("Password", .imageLock, .reddishPink)
                    .padding(.top, 8)

                IndicatorTextField("Date of Birth", .imageCalender, .reddishPink)
                    .padding(.top, 8)

                IndicatorTextField("Gender", .imageUserRed, .reddishPink)
                    .padding(.top, 8)

                Spacer()
                    .frame(width: 0, height: -keyboardObserver.lastViewAdjustment)
                    .animation(.linear(duration: 1))
            }
            .background(GeometryGetter(rect: $keyboardObserver.lastViewRect))

            ...
        }
        .background(BackgroundImage(.imageBgSignup))
        .edgesIgnoringSafeArea(.all)
        .onAppear { self.keyboardObserver.addObserver() }
        .onDisappear { self.keyboardObserver.removeObserver() }
    }
}

IndicatorTextField настроен только для TextField.

Я хочу добавить анимацию на клавиатуре, то есть, когда Spacer имеет высоту 135, которая скоро изменится на 0. Она быстро изменилась без анимации.

Я также пробовал обернуть Spacer блоком withAnimation, но без плодотворного результата.

Есть предложения?

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