如何在SwiftUI的scrollview中的间隔高度变化上添加动画?

时间:2020-01-30 18:14:33

标签: swift swiftui

我有一个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时,它会快速变化而没有动画。

我也尝试用withAnimation块包装Spacer,但没有取得丰硕的成果。

有什么建议吗?

0 个答案:

没有答案