键盘出现时如何显示完整的列表?键盘隐藏在列表的下部。
我的列表行中有一个textField。当键盘出现时,无法向下滚动以查看完整列表。键盘在列表的前面,而不在列表的“下面”。这是我的编码:
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())
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮我怎么做吗?
非常感谢你。
Bog*_*rca 10
另一种实现的KeyboardResponder使用对象Compose,因为看到这里。
final class KeyboardResponder: BindableObject {
let willChange = PassthroughSubject<CGFloat, Never>()
private(set) var currentHeight: Length = 0 {
willSet {
willChange.send(currentHeight)
}
}
let keyboardWillOpen = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.first() // keyboardWillShow notification may be posted repeatedly
.map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
.map { $0.height }
let keyboardWillHide = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in CGFloat(0) }
func listen() {
_ = Publishers.Merge(keyboardWillOpen, keyboardWillHide)
.subscribe(on: RunLoop.main)
.assign(to: \.currentHeight, on: self)
}
init() {
listen()
}
}
Run Code Online (Sandbox Code Playgroud)
更好的方法是将上述内容打包为ViewModifier(从此处宽松地修改):
struct AdaptsToSoftwareKeyboard: ViewModifier {
@State var currentHeight: Length = 0
func body(content: Content) -> some View {
content
.padding(.bottom, currentHeight)
.edgesIgnoringSafeArea(currentHeight == 0 ? Edge.Set() : .bottom)
.onAppear(perform: subscribeToKeyboardEvents)
}
private let keyboardWillOpen = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
.map { $0.height }
private let keyboardWillHide = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in Length.zero }
private func subscribeToKeyboardEvents() {
_ = Publishers.Merge(keyboardWillOpen, keyboardWillHide)
.subscribe(on: RunLoop.main)
.assign(to: \.currentHeight, on: self)
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以这样使用:
Group {
........
}.modifier(AdaptsToSoftwareKeyboard())
Run Code Online (Sandbox Code Playgroud)
这里有一个处理键盘操作的答案,您可以订阅这样的键盘事件:
final class KeyboardResponder: BindableObject {
let didChange = PassthroughSubject<CGFloat, Never>()
private var _center: NotificationCenter
private(set) var currentHeight: CGFloat = 0 {
didSet {
didChange.send(currentHeight)
}
}
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)
}
deinit {
_center.removeObserver(self)
}
@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
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
@State var keyboard = KeyboardResponder()
var body: some View {
List {
VStack {
...
...
...
}.padding(.bottom, keyboard.currentHeight)
}
Run Code Online (Sandbox Code Playgroud)
将Bogdan Farca出色的Combine方法更新为XCode 11.2:
import Combine
import SwiftUI
struct AdaptsToSoftwareKeyboard: ViewModifier {
@State var currentHeight: CGFloat = 0
func body(content: Content) -> some View {
content
.padding(.bottom, self.currentHeight)
.edgesIgnoringSafeArea(self.currentHeight == 0 ? Edge.Set() : .bottom)
.onAppear(perform: subscribeToKeyboardEvents)
}
private let keyboardWillOpen = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
.map { $0.height }
private let keyboardWillHide = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in CGFloat.zero }
private func subscribeToKeyboardEvents() {
_ = Publishers.Merge(keyboardWillOpen, keyboardWillHide)
.subscribe(on: RunLoop.main)
.assign(to: \.self.currentHeight, on: self)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这是实现的更新版本BindableObject(现在命名为ObservableObject)。
import SwiftUI
import Combine
class KeyboardObserver: ObservableObject {
private var cancellable: AnyCancellable?
@Published private(set) var keyboardHeight: CGFloat = 0
let keyboardWillShow = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { ($0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height }
let keyboardWillHide = NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ -> CGFloat in 0 }
init() {
cancellable = Publishers.Merge(keyboardWillShow, keyboardWillHide)
.subscribe(on: RunLoop.main)
.assign(to: \.keyboardHeight, on: self)
}
}
Run Code Online (Sandbox Code Playgroud)
以下是在您的视图中使用它的方法:
@ObservedObject private var keyboardObserver = KeyboardObserver()
var body: some View {
...
YourViewYouWantToRaise()
.padding(.bottom, keyboardObserver.keyboardHeight)
.animation(.easeInOut(duration: 0.3))
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1699 次 |
| 最近记录: |