首页 > 解决方案 > 用于完成按钮的文本字段的 swift ui 扩展

问题描述

我有一个 iOS 应用程序,其中有几个使用 .keyboardType(.decimalPad) 的数字文本字段字段 - 但是没有办法说“是的”我现在已经完成了编辑 - 所以我想在键盘上完成或接受某种操作

当我搜索它时 - 我发现了大量示例,但它们主要与UITextfield相关,而不是文本字段 - 并设置了名为 InputAccessoryView 的东西 - 文本字段显然不支持。当我搜索过滤掉它们时 - 我发现各种奇怪的包装器和一些事情,比如在父组件中添加工具栏,而不是文本字段本身 - 我在很多页面上有很多文本字段,所以真的很想解决它在文本字段级别。

我想要的是构建文本字段的扩展- 这样我就可以添加一个完成按钮来关闭它 - 即这里的代码,但实际编译的东西 - 因为最后一行不起作用:

extension TextField {
    func addDoneButtonOnKeyboard() {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default

        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: nil)

        let items = [flexSpace, done]
        doneToolbar.items = items
        doneToolbar.sizeToFit()

        self.inputAccessoryView = doneToolbar
    }
}

所以我可以在我的 swiftui 代码中说:

     TextField("blah", $blah).addDoneButtonOnKeyboard()

另外 - 我有一些建议指出我其他问题,比如在 UIRepresentable 中包装 UITextField - 以快速访问 UIKit ......但我真的想找到一个解决方案,它是“TextField”的扩展,并且除了使用 3rd 方库“introspect”的建议之外 - 所有其他建议最终都会创建一个新类。

标签: iosswiftswiftui

解决方案


对于任何感兴趣的人-我无论如何都找不到内省(有一天我会看看它在做什么并拉出关键部分)-但它确实给了我一个解决方案-所以有了这个扩展:

public extension TextField
{
    func addDoneButtonOnKeyboard() -> some View
    {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: nil, action: nil)
        doneToolbar.items = [flexSpace, done]
        doneToolbar.sizeToFit()
        return self.introspectTextField
        {
            text_field in
            text_field.inputAccessoryView = doneToolbar
            done.target = text_field
            done.action = #selector( text_field.resignFirstResponder )
        }
    }
}

您所要做的就是将 .addDoneButtonOnKeyboard() 添加到视图中的文本字段。


推荐阅读