如何在隐藏键盘时排除文本字段的点击

huangapple go评论68阅读模式
英文:

How to exclude TextField tap while hiding keyboard

问题

目前,我在用户点击任何地方时都会隐藏键盘。我希望排除两个TextField的点击以避免键盘的隐藏和显示效果。

我想要:

  1. 对于我的TextField,希望有一个稳定的键盘,没有隐藏和显示的效果。
  2. 点击任何地方来关闭/隐藏键盘。

请查看以下效果:

如何在隐藏键盘时排除文本字段的点击

英文:

Currently, I am hiding the keyboard when the user taps anywhere. I want to exclude 2 TextFields tap to avoid the keyboard hide/show effect.

import SwiftUI

struct ContentView: View {

	@FocusState var focus:FocusedField?
	@State var name = ""
	@State var email = ""
	@State var phoneNumber = ""

	var body: some View {
		List {
			TextField("Name:",text: $name)
				.focused($focus, equals: .name)
				.onSubmit {
					focus = .email
				}
			TextField("Email:",text: $email)
				.focused($focus, equals: .email)
				.onSubmit {
					focus = .phone
				}
			TextField("PhoneNumber:", text: $phoneNumber)
				.focused($focus, equals: .phone)
				.onSubmit {
					if !name.isEmpty && !email.isEmpty && !phoneNumber.isEmpty {
						submit()
					}
				}
		}
		.onTapGesture {
			if (focus != nil) {
				hideKeyboard()
			}
		}
	}

	private func submit() {
        print("submit")
    }
	
	enum FocusedField: Hashable {
		case name, email, phone
	}
}

extension View {
	func hideKeyboard() {
		print("hideKeyboard")
		let resign = #selector(UIResponder.resignFirstResponder)
		UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
	}
}

I want:

  1. A stable keyboard for my TextFields with no hide and show effects.
  2. Tap anywhere to dismiss/hide the keyboard.

Please see the following effects:

如何在隐藏键盘时排除文本字段的点击

答案1

得分: 0

有一个在iOS 16及以后可用的键盘隐藏修饰符:

func scrollDismissesKeyboard(_ mode: ScrollDismissesKeyboardMode) -> some View

您可能希望使用 immediately 模式。

var body: some View{
    List {
        // 等等。
    }
    .scrollDismissesKeyboard(.immediately)
}

这不是在点击时隐藏键盘,而是在滚动时隐藏,这是典型的iOS行为。

英文:

There is a modifier that defines keyboard dismissal available since iOS 16:

func scrollDismissesKeyboard(_ mode: ScrollDismissesKeyboardMode) -> some View

You probably want the immediately mode.

var body: some View{
    List {
        // etc.  
    }
    .scrollDismissesKeyboard(.immediately)
}

This does not dismiss the keyboard on tap but on scroll which is the typical iOS behaviour.

答案2

得分: 0

I found the answer.

public struct TapToHideKeyboardView: View {
    
    public init() {
    }
    
    public var body: some View {
        Button(action: {
            self.hideKeyboard()
        }) {
            Rectangle().foregroundColor(.brown)
        }
        .background(
            GeometryReader { geometry in
                Color.clear
                    .frame(width: geometry.size.width, height: geometry.size.height)
            }
                .onTapGesture {
                    self.hideKeyboard()
                }
        )
    }
    
    func hideKeyboard() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

Use this public struct inside Zstack.

var body: some View{
        NavigationStack{
            ZStack {
                TapToHideKeyboardView()
                VStack{
                    TextField("Name:",text:$name)
                        .focused($focus, equals: .name)
                        .onSubmit {
                            focus = .email
                        }
                    TextField("Email:",text:$email)
                        .focused($focus,equals: .email)
                        .onSubmit {
                            focus = .phone
                        }
                    TextField("PhoneNumber:",text:$phoneNumber)
                        .focused($focus, equals: .phone)
                        .onSubmit {
                            if !name.isEmpty && !email.isEmpty && !phoneNumber.isEmpty {
                                submit()
                            }
                        }
                }
            }
        }
    }
英文:

I found the answer.

public struct TapToHideKeyboardView: View {
    
    public init() {
    }
    
    public var body: some View {
        Button(action: {
            self.hideKeyboard()
        }) {
            Rectangle().foregroundColor(.brown)
        }
        .background(
            GeometryReader { geometry in
                Color.clear
                    .frame(width: geometry.size.width, height: geometry.size.height)
            }
                .onTapGesture {
                    self.hideKeyboard()
                }
        )
    }
    
    func hideKeyboard() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

Use this public struct inside Zstack.

var body: some View{
        NavigationStack{
            ZStack {
                TapToHideKeyboardView()
                VStack{
                    TextField("Name:",text:$name)
                        .focused($focus, equals: .name)
                        .onSubmit {
                            focus = .email
                        }
                    TextField("Email:",text:$email)
                        .focused($focus,equals: .email)
                        .onSubmit {
                            focus = .phone
                        }
                    TextField("PhoneNumber:",text:$phoneNumber)
                        .focused($focus, equals: .phone)
                        .onSubmit {
                            if !name.isEmpty && !email.isEmpty && !phoneNumber.isEmpty {
                                submit()
                            }
                        }
                }
            }
        }
    }

huangapple
  • 本文由 发表于 2023年7月18日 13:24:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76709716.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定