SwiftUI中是否有一个与InputAccessoryView等效的东西(或任何迹象表明即将出现?)
如果没有,您将如何模拟InputAccessoryView的行为(即固定在键盘顶部的视图)?所需的行为类似于iMessage,在屏幕底部固定有一个视图,该视图在键盘打开时位于上方,并直接位于键盘上方。例如:
答案 0 :(得分:4)
我得到了一些可以满足预期结果的方法。因此,一开始,仅使用SwiftUI不可能做到这一点。您仍然必须使用UIKit通过所需的“ inputAccessoryView”创建UITextField。 SwiftUI中的文本字段没有特定的方法。
首先,我创建了一个新结构:
import UIKit
import SwiftUI
struct InputAccessory: UIViewRepresentable {
func makeUIView(context: Context) -> UITextField {
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 44))
customView.backgroundColor = UIColor.red
let sampleTextField = UITextField(frame: CGRect(x: 20, y: 100, width: 300, height: 40))
sampleTextField.inputAccessoryView = customView
sampleTextField.placeholder = "placeholder"
return sampleTextField
}
func updateUIView(_ uiView: UITextField, context: Context) {
}
}
最终,我可以在视图主体中创建一个新的文本字段:
import SwiftUI
struct Test: View {
@State private var showInput: Bool = false
var body: some View {
HStack{
Spacer()
if showInput{
InputAccessory()
}else{
InputAccessory().hidden()
}
}
}
}
现在,您可以使用“ showInput”状态隐藏和显示文本字段。下一个问题是,您必须在特定事件中打开键盘并显示文本字段。 SwiftUI再次无法实现,您必须返回UiKit使其成为第一响应者。如果尝试使用我的代码,键盘上方应该会显示红色背景。现在,您只需向上移动字段,便可以使用版本。
总体而言,在当前状态下,无法使用键盘或某些textfield方法工作。
答案 1 :(得分:2)
macOS 12.0+,Mac Catalyst 15.0+
ToolbarItemPlacement
在 iOS 15.0+ 中有一个新属性
keyboard
在 iOS 上,键盘项在存在时位于软件键盘上方,或者在连接了硬件键盘时位于屏幕底部。 在 macOS 上,键盘项目将放置在触控栏中。 https://developer.apple.com
struct LoginForm: View {
@State private var username = ""
@State private var password = ""
var body: some View {
Form {
TextField("Username", text: $username)
SecureField("Password", text: $password)
}
.toolbar(content: {
ToolbarItemGroup(placement: .keyboard, content: {
Text("Left")
Spacer()
Text("Right")
})
})
}
}
答案 2 :(得分:1)
在 Swift Student 的 this post 的帮助下,我设法创建了一个很好的工作解决方案,并进行了大量修改和添加了您在 UIKit 中认为理所当然的功能。它是 UITextField 的包装器,但它对用户完全隐藏,并且它的实现非常 SwiftUI。您可以在我的 GitHub repo 中查看它 - 您可以将它作为 Swift 包引入到您的项目中。
(有太多代码无法放在这个答案中,因此链接到 repo)
答案 3 :(得分:0)
我已经在iOS 14上使用99%纯SwiftUI解决了这个问题。 在工具栏中,您可以显示任何您喜欢的视图。
那是我的实现方式
import SwiftUI
struct ContentView: View {
@State private var showtextFieldToolbar = false
@State private var text = ""
var body: some View {
ZStack {
VStack {
TextField("Write here", text: $text) { isChanged in
if isChanged {
showtextFieldToolbar = true
}
} onCommit: {
showtextFieldToolbar = false
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}
VStack {
Spacer()
if showtextFieldToolbar {
HStack {
Spacer()
Button("Close") {
showtextFieldToolbar = false
UIApplication.shared
.sendAction(#selector(UIResponder.resignFirstResponder),
to: nil, from: nil, for: nil)
}
.foregroundColor(Color.black)
.padding(.trailing, 12)
}
.frame(idealWidth: .infinity, maxWidth: .infinity,
idealHeight: 44, maxHeight: 44,
alignment: .center)
.background(Color.gray)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
答案 4 :(得分:0)
我有一个可以自定义工具栏的实现
public struct InputTextField<Content: View>: View {
private let placeholder: LocalizedStringKey
@Binding
private var text: String
private let onEditingChanged: (Bool) -> Void
private let onCommit: () -> Void
private let content: () -> Content
@State
private var isShowingToolbar: Bool = false
public init(placeholder: LocalizedStringKey = "",
text: Binding<String>,
onEditingChanged: @escaping (Bool) -> Void = { _ in },
onCommit: @escaping () -> Void = { },
@ViewBuilder content: @escaping () -> Content) {
self.placeholder = placeholder
self._text = text
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
self.content = content
}
public var body: some View {
ZStack {
TextField(placeholder, text: $text) { isChanged in
if isChanged {
isShowingToolbar = true
}
onEditingChanged(isChanged)
} onCommit: {
isShowingToolbar = false
onCommit()
}
.textFieldStyle(RoundedBorderTextFieldStyle())
VStack {
Spacer()
if isShowingToolbar {
content()
}
}
}
}
}