Comment est-il possible d'afficher la liste complète lorsque le clavier apparaît? Le clavier cache la partie inférieure de la liste.
J'ai un textField dans ma ligne de liste. Lorsque le clavier apparaît, il n'est pas possible de faire défiler vers le bas pour voir la liste complète. Le clavier est en face de la liste et non "sous" la liste. Voici mon codage:
struct ContentView: View {
@State private var name = ""
var body: some View {
List {
VStack {
Text("Begin")
.frame(width: UIScreen.main.bounds.width)
.padding(.bottom, 400)
.background(Color.red)
TextField($name, placeholder: Text("enter text"), onEditingChanged: { _ in
//
}) {
//
}
Text("End")
.frame(width: UIScreen.main.bounds.width)
.padding(.top, 400)
.background(Color.green)
}
.listRowInsets(EdgeInsets())
}
}
}
Quelqu'un peut-il m'aider à faire cela?
Merci beaucoup.
Demandez à un observateur de définir un EnvironmentValue
. Faites-en ensuite une variable dans votre vue:
@Environment(\.keyboardHeight) var keyboardHeight: CGFloat
import SwiftUI
import UIKit
extension EnvironmentValues {
var keyboardHeight : CGFloat {
get { EnvironmentObserver.shared.keyboardHeight }
}
}
class EnvironmentObserver {
static let shared = EnvironmentObserver()
var keyboardHeight: CGFloat = 0 {
didSet { print("Keyboard height \(keyboardHeight)") }
}
init() {
// MARK: Keyboard Events
NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: OperationQueue.main) { [weak self ] (notification) in
self?.keyboardHeight = 0
}
let handler: (Notification) -> Void = { [weak self] notification in
guard let userInfo = notification.userInfo else { return }
guard let frame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
// From Apple docs:
// The rectangle contained in the UIKeyboardFrameBeginUserInfoKey and UIKeyboardFrameEndUserInfoKey properties of the userInfo dictionary should be used only for the size information it contains. Do not use the Origin of the rectangle (which is always {0.0, 0.0}) in rectangle-intersection operations. Because the keyboard is animated into position, the actual bounding rectangle of the keyboard changes over time.
self?.keyboardHeight = frame.size.height
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification, object: nil, queue: OperationQueue.main, using: handler)
NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidChangeFrameNotification, object: nil, queue: OperationQueue.main, using: handler)
}
Ces exemples sont un peu anciens, j'ai réorganisé du code pour utiliser les nouvelles fonctionnalités récemment ajoutées à SwiftUI, une explication détaillée du code utilisé dans cet exemple peut être trouvée dans cet article: Article Describing ObservableObject
Classe d'observateur de clavier:
import SwiftUI
import Combine
final class KeyboardResponder: ObservableObject {
let objectWillChange = ObservableObjectPublisher()
private var _center: NotificationCenter
@Published var currentHeight: CGFloat = 0
init(center: NotificationCenter = .default) {
_center = center
_center.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
_center.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyBoardWillShow(notification: Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
currentHeight = keyboardSize.height
}
}
@objc func keyBoardWillHide(notification: Notification) {
currentHeight = 0
}
}
Usage:
@ObservedObject private var keyboard = KeyboardResponder()
VStack {
//Views here
}
//Makes it go up, since negative offset
.offset(y: -self.keyboard.currentHeight)