swift 如何检测快捷键中是否存在键盘

8xiog9wr  于 2023-03-11  发布在  Swift
关注(0)|答案(3)|浏览(184)

我想知道按下按钮时键盘是否存在。我该怎么做?我试过了,但没有任何结果。谢谢。

k97glaaz

k97glaaz1#

使用这个协议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()
    }
}

它的工作原理是使用合并并创建一个发布者,这样我们就可以接收键盘通知。
以下是如何应用该技术的示例:

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
            }
    }
}

现在,您可以从isKeyboardVisible变量中读取,以了解键盘是否可见。
TextField处于活动状态且显示键盘时,将打印以下内容:
键盘是否可见?true
当键盘在按回车键时隐藏时,将打印以下内容:
键盘是否可见?false
您可以使用keyboardWillShowNotification/keyboardWillHideNotification在键盘开始出现或消失时进行更新,使用keyboardDidShowNotification/keyboardDidHideNotification变体在键盘出现或消失后进行更新。我更喜欢will变体,因为键盘显示时更新是即时的。

mm9b1k5b

mm9b1k5b2#

iOS 15:

您可以使用focused(_:)视图修饰符和@FocusState属性 Package 来了解文本字段是否正在编辑,以及更改编辑状态。

@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
            }
        }
    }
}
8cdiaqws

8cdiaqws3#

“我的小小进步”乔治回答。
在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()
  }
}

我还添加了debounce操作符,以防止当您有多个TextField并且用户在它们之间移动时发生真-假切换。
在任何视图中使用

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
    }
  }
}

相关问题