gpt4 book ai didi

ios - iOS:如何在键盘按键后停止接收keyboardWillShowNotification

转载 作者:行者123 更新时间:2023-12-01 21:54:31 26 4
gpt4 key购买 nike

我正在尝试进行键盘自适应行为。我已经订阅了keyboardWillShowNotificationkeyboardWillHideNotification,我收到了所有预期的事件。但是我对keyboardWillShowNotification有问题:按下键盘按钮后,我收到了它一次:

Example

这是我的侦听器的代码:

import SwiftUI
import Combine

// MARK: - View

struct ContentView: View {
@State private var text: String = ""

var body: some View {
VStack{
Text(text)
Spacer()
TextField("Input your text", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding()
.keyboardAdaptive()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

// MARK: - Keyboard hacks

extension Notification {
var keyboardHeight: CGFloat {
return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
}
}

extension Publishers {
static var keyboardHeight: AnyPublisher<CGFloat, Never> {
let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
.map { (n: Notification) -> CGFloat in
print("will show")
return n.keyboardHeight
}

let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification)
.map { (n: Notification) -> CGFloat in
print("will hide")
return CGFloat(0)
}

return MergeMany(willShow, willHide)
.eraseToAnyPublisher()
}
}

// MARK: -- Detect focused element
extension UIResponder {
static var currentFirstResponder: UIResponder? {
_currentFirstResponder = nil
UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)
return _currentFirstResponder
}

private static weak var _currentFirstResponder: UIResponder?

@objc private func findFirstResponder(_ sender: Any) {
UIResponder._currentFirstResponder = self
}

var globalFrame: CGRect? {
guard let view = self as? UIView else { return nil }
return view.superview?.convert(view.frame, to: nil)
}
}

// MARK: -- Keyboard Adaptive Modifier

struct KeyboardAdaptive: ViewModifier {
@State private var bottomPadding: CGFloat = 0

func body(content: Content) -> some View {
GeometryReader { geometry in
content
.padding(.bottom, self.bottomPadding)
.onReceive(Publishers.keyboardHeight) { keyboardHeight in
let keyboardTop = geometry.frame(in: .global).height - keyboardHeight
let focusedTextInputBottom = UIResponder.currentFirstResponder?.globalFrame?.maxY ?? 0
self.bottomPadding = max(0, focusedTextInputBottom - keyboardTop - geometry.safeAreaInsets.bottom)
}
.animation(.easeOut(duration: 0.16))
}
}
}

extension View {
func keyboardAdaptive() -> some View {
ModifiedContent(content: self, modifier: KeyboardAdaptive())
}
}

我是移动开发领域的新手,有人可以帮助我吗?

最佳答案

简单的是忽略相同的条件,如下所示。经过Xcode 11.4 / iOS 13.4测试

demo

struct KeyboardAdaptive: ViewModifier {
@State private var bottomPadding: CGFloat = 0

func body(content: Content) -> some View {
GeometryReader { geometry in
content
.padding(.bottom, self.bottomPadding)
.onReceive(Publishers.keyboardHeight) { keyboardHeight in
// Just ignore equal resend
if keyboardHeight > 0 && self.bottomPadding > 0 { return } // << here !!

let keyboardTop = geometry.frame(in: .global).height - keyboardHeight
let focusedTextInputBottom = UIResponder.currentFirstResponder?.globalFrame?.maxY ?? 0
self.bottomPadding = max(0, focusedTextInputBottom - keyboardTop - geometry.safeAreaInsets.bottom)
}
.animation(.easeOut(duration: 0.16))
}
}
}

关于ios - iOS:如何在键盘按键后停止接收keyboardWillShowNotification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61381303/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com