Max*_*Max 27
我的一点改进@George的回答。
在 View 协议中实现发布者
import Combine
extension View {
var keyboardPublisher: AnyPublisher<Bool, Never> {
Publishers
.Merge(
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { _ in true },
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in false })
.debounce(for: .seconds(0.1), scheduler: RunLoop.main)
.eraseToAnyPublisher()
}
}
Run Code Online (Sandbox Code Playgroud)
我还添加了去抖动运算符,以便当您有多个文本字段并且用户在它们之间移动时防止 true - false 切换。
在任何视图中使用
struct SwiftUIView: View {
@State var isKeyboardPresented = false
@State var firstTextField = ""
@State var secondTextField = ""
var body: some View {
VStack {
TextField("First textField", text: $firstTextField)
TextField("Second textField", text: $secondTextField)
}
.onReceive(keyboardPublisher) { value in
isKeyboardPresented = value
}
}
}
Run Code Online (Sandbox Code Playgroud)
Eil*_*lon 15
您可以使用focused(_:)视图修饰符和@FocusState属性包装器来了解文本字段是否正在编辑,还可以更改编辑状态。
@State private var text: String = ""
@FocusState private var isTextFieldFocused: Bool
var body: some View {
VStack {
TextField("hello", text: $text)
.focused($isTextFieldFocused)
if isTextFieldFocused {
Button("Keyboard is up!") {
isTextFieldFocused = false
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Con*_*lon 12
有了环境钥匙...
采用@Lepidopteron 的答案,但用它来驱动环境密钥。
这允许您在任何视图中使用访问键盘状态
@Environment(\.keyboardShowing) var keyboardShowing
Run Code Online (Sandbox Code Playgroud)
您所要做的就是在层次结构的顶部添加一个视图修饰符
RootView()
.addKeyboardVisibilityToEnvironment()
Run Code Online (Sandbox Code Playgroud)
这全部由以下 ViewModifier 文件提供支持...
public extension View {
/// Sets an environment value for keyboardShowing
/// Access this in any child view with
/// @Environment(\.keyboardShowing) var keyboardShowing
func addKeyboardVisibilityToEnvironment() -> some View {
modifier(KeyboardVisibility())
}
}
private struct KeyboardShowingEnvironmentKey: EnvironmentKey {
static let defaultValue: Bool = false
}
extension EnvironmentValues {
var keyboardShowing: Bool {
get { self[KeyboardShowingEnvironmentKey.self] }
set { self[KeyboardShowingEnvironmentKey.self] = newValue }
}
}
private struct KeyboardVisibility:ViewModifier {
#if os(macOS)
fileprivate func body(content: Content) -> some View {
content
.environment(\.keyboardShowing, false)
}
#else
@State var isKeyboardShowing:Bool = false
private var keyboardPublisher: AnyPublisher<Bool, Never> {
Publishers
.Merge(
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { _ in true },
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in false })
.debounce(for: .seconds(0.1), scheduler: RunLoop.main)
.eraseToAnyPublisher()
}
fileprivate func body(content: Content) -> some View {
content
.environment(\.keyboardShowing, isKeyboardShowing)
.onReceive(keyboardPublisher) { value in
isKeyboardShowing = value
}
}
#endif
}
Run Code Online (Sandbox Code Playgroud)
使用此协议,KeyboardReadable您可以遵循任何协议View并从中获取键盘更新。
KeyboardReadable 协议:
import Combine
import UIKit
/// Publisher to read keyboard changes.
protocol KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> { get }
}
extension KeyboardReadable {
var keyboardPublisher: AnyPublisher<Bool, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { _ in true },
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in false }
)
.eraseToAnyPublisher()
}
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理是使用 Combine 并创建一个发布者,以便我们可以接收键盘通知。
通过如何应用它的示例视图:
struct ContentView: View, KeyboardReadable {
@State private var text: String = ""
@State private var isKeyboardVisible = false
var body: some View {
TextField("Text", text: $text)
.onReceive(keyboardPublisher) { newIsKeyboardVisible in
print("Is keyboard visible? ", newIsKeyboardVisible)
isKeyboardVisible = newIsKeyboardVisible
}
}
}
Run Code Online (Sandbox Code Playgroud)
您现在可以从isKeyboardVisible变量中读取以了解键盘是否可见。
当TextField显示键盘处于活动状态时,将打印以下内容:
键盘是否可见?真的
当键盘在按回车键时隐藏时,将打印以下内容:
键盘是否可见?错误的
您可以在键盘开始出现或消失时使用keyboardWillShowNotification/keyboardWillHideNotification进行更新,并在键盘出现或消失后使用keyboardDidShowNotification/keyboardDidHideNotification变体进行更新。我更喜欢这个will变体,因为当键盘显示时更新是即时的。
| 归档时间: |
|
| 查看次数: |
577 次 |
| 最近记录: |