【问题标题】:SwiftUI - Adding a keyboard toolbar button for only one TextField adds it for all TextFieldsSwiftUI - 仅为一个 TextField 添加键盘工具栏按钮,为所有 TextField 添加它
【发布时间】:2021-12-28 19:40:45
【问题描述】:

背景

我有两个TextFields,其中一个的键盘类型为.decimalPad

鉴于使用小数点键盘关闭它时没有“完成”按钮,就像标准键盘的返回键一样,我想在小键盘上方的工具栏中添加一个“完成”按钮 仅适用于 SwiftUI 中的十进制键盘

问题

添加.toolbar 到任何TextField 出于某种原因将其添加到所有TextFields 中!我尝试了条件修饰符,使用聚焦状态并检查 Field 值(但由于某种原因,它在检查时没有设置,也许是一个排序的东西?)它仍然在键盘上方为 TextFields 添加了工具栏.

我的单个TextField 只能有一个.toolbar,它接受数字,而不是另一个TextField,它接受一个字符串?

代码

请注意,我尝试制作一个最小的示例,您可以复制并粘贴到 Xcode 中并自己运行它。使用 Xcode 13.2 时,为我显示 TextFields 的键盘存在一些问题,尤其是在工作表中,因此可能需要模拟器才能正确运行它并使用 cmd+K 调出键盘。

import SwiftUI

struct TestKeyboard: View {
    @State var str: String = ""
    @State var num: Float = 1.2

    @FocusState private var focusedField: Field?
    private enum Field: Int, CaseIterable {
        case amount
        case str
    }

    var body: some View {
        VStack {
            Spacer()
            
            // I'm not adding .toolbar here...
            TextField("A text field here", text: $str)
                .focused($focusedField, equals: .str)

            // I'm only adding .toolbar here, but it still shows for the one above..
            TextField("", value: $num, formatter: FloatNumberFormatter())
                .keyboardType(.decimalPad)
                .focused($focusedField, equals: .amount)
                .toolbar {
                    ToolbarItem(placement: .keyboard) {
                        Button("Done") {
                            focusedField = nil
                        }
                    }
                }

            Spacer()
        }
    }
}

class FloatNumberFormatter: NumberFormatter {
    override init() {
        super.init()
        
        self.numberStyle = .currency        
        self.currencySymbol = "€"
        self.minimumFractionDigits = 2
        self.maximumFractionDigits = 2
        self.locale = Locale.current
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
}

// So you can preview it quickly
struct TestKeyboard_Previews: PreviewProvider {
    static var previews: some View {
        TestKeyboard()
    }
}

【问题讨论】:

  • 只要它们在同一个视图中,两个键盘都会有完成按钮。这就是toolbar 的工作方式。有一些 iOS 15 之前的教程介绍了如何将按钮添加到键盘上,以实现您想要的功能。见this answer
  • @Yrb 我几乎有你的建议使用浮动,但使用NumberFormatter 不起作用,视图占据了屏幕的其余部分。它的行为不像我预期的那样。还有什么我想念的吗? Code。 PS - 再次感谢您的回复!
  • 我可以使用numberFormatter.string(from: NSNumber(value: value))!。但是您可以删除该符号。与我尝试使用 SwiftUI 处理 iOS 15 特定的东西相比,我觉得这是一个相当大的技巧。

标签: swift swiftui swiftui-toolbar


【解决方案1】:

尝试使工具栏内容有条件并将工具栏移到外面,如下所示。 (现在无法测试 - 只是想法)

注意:在真机上测试

var body: some View {
    VStack {
        Spacer()
        
        TextField("A text field here", text: $str)
            .focused($focusedField, equals: .str)

        TextField("", value: $num, formatter: FloatNumberFormatter())
            .focused($focusedField, equals: .amount)
            .keyboardType(.decimalPad)

        Spacer()
    }
    .toolbar {          // << here !!
        ToolbarItem(placement: .keyboard) {
            if field == .amount {             // << here !!
               Button("Done") {
                  focusedField = nil
               }
            }
        }
    }

}

【讨论】:

    【解决方案2】:

    我发现将每个TextField 包装在自己的NavigationView 中会为每个NavigationView 提供自己的上下文,从而获得一个独特的工具栏。感觉不对,我在控制台中看到了约束警告。使用这样的东西:

       var body: some View {
        VStack {
            Spacer()
            
            // I'm not adding .toolbar here...
            NavigationView {
              TextField("A text field here", text: $str)
                .focused($focusedField, equals: .str)
            }
            // I'm only adding .toolbar here, but it still shows for the one above..
            NavigationView {
              TextField("", value: $num, formatter: FloatNumberFormatter())
                .keyboardType(.decimalPad)
                .focused($focusedField, equals: .amount)
                .toolbar {
                    ToolbarItem(placement: .keyboard) {
                        Button("Done") {
                            focusedField = nil
                        }
                    }
                }
            }
            Spacer()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多