swift 在改变偏移量后将轻击手势添加到空白区域

5anewei6  于 2023-06-21  发布在  Swift
关注(0)|答案(2)|浏览(68)

当键盘可见时,我为TextField实现了y偏移机制。点击时,整个屏幕向上移动。现在,我想点击任何空白的空间来关闭键盘。问题是偏移量所赋予的增加的空间没有接收到我的点击手势。

struct LoginView: View {
    @State private var email = ""
    @State private var password = ""

    @State private var keyboardYOffset = CGFloat(0)

    var body: some View {
        VStack {
            VStack(spacing: 32) {

             Rectangle()
                .frame(width: 187, height: 208)
                .padding(.top, 56)
                .padding(.bottom, 94)
                .background(Color.red)

                TextField("Email", text: $email)
                    .frame(maxWidth: .infinity)
                    .frame(height: 50)
                // inset of the placeholder text
                    .padding(.horizontal)
                    .border(Color.red)
                // inset of the entire textfield
                    .padding(.horizontal)

                SecureField("Password", text: $email)
                    .frame(maxWidth: .infinity)
                    .frame(height: 50)
                // inset of the placeholder text
                    .padding(.horizontal)
                    .border(Color.red)
                // inset of the entire textfield
                    .padding(.horizontal)

                Spacer()
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(.top, 32)
            .background(Color.white.ignoresSafeArea())
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .background(Theme.BrandColor.primary.ignoresSafeArea())
        .offset(y: -keyboardYOffset)
        .animation(.easeInOut(duration: 1), value: keyboardYOffset)
        .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
            let value = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
            let keyboardHeight = value?.height ?? 0
            // for our purposes we only need to offset by half the keyboard height
            self.keyboardYOffset = keyboardHeight / 2
        }
        .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
            self.keyboardYOffset = 0
        }
        .onTapGesture {
            UIApplication.shared.endEditing()
        }
    }
}

struct LoginView_Previews: PreviewProvider {
    static var previews: some View {
        LoginView()
    }
}

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

我试过在任何地方添加一个点击手势识别器,但都无济于事。

6jjcrrmo

6jjcrrmo1#

通过将contentShape修饰符添加到最外层VStack修复了该问题

.contentShape(Rectangle())
.onTapGesture {
   UIApplication.shared.endEditing()
}
ujv3wf0j

ujv3wf0j2#

试试这个:

import SwiftUI

struct LoginView: View {
    @State private var email = ""
    @State private var password = ""
    
    @State private var keyboardYOffset = CGFloat(0)
    
    var body: some View {
        VStack {
            VStack(spacing: 32) {
                Rectangle()
                    .frame(width: 187, height: 208)
                    .padding(.top, 56)
                    .padding(.bottom, 94)
                    .background(Color.red)
                
                TextField("Email", text: $email)
                    .frame(maxWidth: .infinity)
                    .frame(height: 50)
                    .padding(.horizontal)
                    .border(Color.red)
                    .padding(.horizontal)
                
                SecureField("Password", text: $password)
                    .frame(maxWidth: .infinity)
                    .frame(height: 50)
                    .padding(.horizontal)
                    .border(Color.red)
                    .padding(.horizontal)
                
                Spacer()
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(.top, 32)
            .background(Color.white.ignoresSafeArea().onTapGesture {
                UIApplication.shared.endEditing()
            })
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .background(Color.blue.ignoresSafeArea())
        .offset(y: -keyboardYOffset)
        .animation(.easeInOut(duration: 1), value: keyboardYOffset)
        .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
            let value = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
            let keyboardHeight = value?.height ?? 0
            self.keyboardYOffset = keyboardHeight / 2
        }
        .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
            self.keyboardYOffset = 0
        }
    }
}

struct LoginView_Previews: PreviewProvider {
    static var previews: some View {
        LoginView()
    }
}

extension UIApplication {
    func endEditing() {
        windows.forEach { $0.endEditing(false) }
    }
}

相关问题