gpt4 book ai didi

SwiftUI inputAccessoryView 实现

转载 作者:行者123 更新时间:2023-12-05 08:20:12 33 4
gpt4 key购买 nike

我正在尝试在 SwiftUI 中的 TextField 上实现一个 inputAccessoryView。目标是在键盘上方出现一个“完成”按钮,按下该按钮时会摆脱键盘(即 resignFirstResponder())。

我看到了以下 Medium 文章,它声称完全按照我的要求实现了这种行为,但是,我正在努力让它发挥作用。

Medium link containing method to be implemented.

我曾尝试在一个空白的 XCode 项目中实现它,我的代码可以编译,但是,TextField 从未出现,而且我无法触摸应该调出键盘的区域。我如何正确实现此代码以获得所需的行为?

代码

    import Foundation
import UIKit
import SwiftUI

class TextFieldViewController
: UIViewController {

// our custom text field will report changes to the outside
let text: Binding<String>?

// if the toolbar (see below) is used (Done), the keyboard shall be dismissed
// and optionally we execute a provided closure
let onDismiss: (() -> Void)?

init (
text: Binding<String>
, onDismiss: (() -> Void)?) {

self.text = text
self.onDismiss = onDismiss

super.init(
nibName: nil //"<XIB>"
, bundle: nil //Bundle.main?
)
}

required init?(coder: NSCoder) {
self.text = nil
self.onDismiss = nil

super.init(coder: coder)
}

// helper function to encapsulate calling the "view" of UIViewController
fileprivate func getTextField() -> UITextField? {
return view as? UITextField
}

override func viewDidLoad() {
let textField = self.getTextField()
guard textField != nil else {
return
}

// configure a toolbar with a Done button
let toolbar = UIToolbar()
toolbar.setItems([
// just moves the Done item to the right
UIBarButtonItem(
barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace
, target: nil
, action: nil
)
, UIBarButtonItem(
title: "Done"
, style: UIBarButtonItem.Style.done
, target: self
, action: #selector(self.onSet)
)
]
, animated: true
)
toolbar.barStyle = UIBarStyle.default
toolbar.sizeToFit()
textField?.inputAccessoryView = toolbar
}

@objc private func onSet() {
let textField = self.getTextField()
textField?.resignFirstResponder()

self.text?.wrappedValue = textField?.text ?? ""
self.onDismiss?()
}

}

// The SwiftUI view, wrapping the UITextField
struct TextFieldView: View {

var text: Binding<String>
var onDismissKeyboard: (() -> Void)?

var body: some View {
TextFieldRepresentable(
text: self.text
, dismissKeyboardCallback: self.onDismissKeyboard
)
}
}

// The UIViewControllerRepresentable, feeding and controlling the UIViewController
struct TextFieldRepresentable
: UIViewControllerRepresentable {

// the callback
let dismissKeyboardCallback: (() -> Void)?

// created in the previous file/gist
let viewController: TextFieldViewController

init (
text: Binding<String>
, dismissKeyboardCallback: (() -> Void)?) {

self.dismissKeyboardCallback = dismissKeyboardCallback
self.viewController = TextFieldViewController(
text: text
, onDismiss: dismissKeyboardCallback
)
}

// UIViewControllerRepresentable
func makeUIViewController(context: Context) -> UIViewController {

return viewController
}

// UIViewControllerRepresentable
func updateUIViewController(_ viewController: UIViewController, context: Context) {
}

}

struct ContentView : View {

@State var email:String = ""

var body: some View {

HStack{
Circle()
TextFieldView(text: $email)
Circle()
}
}
}

最佳答案

这是一个带有自定义工具栏和输入文本绑定(bind)的演示,但通过排除关闭回调进行了简化(因为它对于方法演示并不重要),只是为了减少代码。希望对您有所帮助。

import SwiftUI
import UIKit
import Combine

struct CustomInputTextField : UIViewRepresentable {

@Binding var text: String

let textField = UITextField(frame: CGRect(x:0, y:0, width: 100, height: 32)) // just any

func makeUIView(context: UIViewRepresentableContext<CustomInputTextField>) -> UITextField {
return textField
}

func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomInputTextField>) {
self.textField.text = text
}

func makeCoordinator() -> CustomInputTextField.Coordinator {
let coordinator = Coordinator(self)

// configure a toolbar with a Done button
let toolbar = UIToolbar()
toolbar.setItems([
// just moves the Done item to the right
UIBarButtonItem(
barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace
, target: nil
, action: nil
)
, UIBarButtonItem(
title: "Done"
, style: UIBarButtonItem.Style.done
, target: coordinator
, action: #selector(coordinator.onSet)
)
]
, animated: true
)
toolbar.barStyle = UIBarStyle.default
toolbar.sizeToFit()

textField.inputAccessoryView = toolbar
return coordinator
}

typealias UIViewType = UITextField

class Coordinator: NSObject {
let owner: CustomInputTextField
private var subscriber: AnyCancellable

init(_ owner: CustomInputTextField) {
self.owner = owner
subscriber = NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: owner.textField)
.sink(receiveValue: { _ in
owner.$text.wrappedValue = owner.textField.text ?? ""
})
}

@objc fileprivate func onSet() {
owner.textField.resignFirstResponder()
}

}
}

struct DemoCustomKeyboardInput : View {

@State var email:String = ""

var body: some View {
VStack{
CustomInputTextField(text: $email).border(Color.black)
.padding(.horizontal)
.frame(maxHeight: 32)
Divider()
Text("Entered text: \(email)")
}
}
}

struct DemoCustomKeyboardInput_Previews: PreviewProvider {
static var previews: some View {
DemoCustomKeyboardInput()
}
}

关于SwiftUI inputAccessoryView 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59114647/

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