NumberField 或如何让 TextField 输入 Double、Float 或其他带点的数字

2023-11-30

根据评论这个问题我做了一个自定义的 SwiftUIView基于一个TextField。它使用数字键盘,只能输入数字和点,只能输入一个点(点),并且可以通过Bindable Double @State价值通过View用于输入。 但有一个错误:当您删除“xxx.0”中的最后一个零时 - 零仍然出现。当你删除一个点时 - 零变成整数的一部分,所以它变成“xxx0”

some behavior

知道如何修复它吗?我试图在删除点之前的最后一个数字时将 value 设置为整数 - 但我无法捕捉到字符串中只有最后一个点的时刻。

这是完整的代码:

import SwiftUI
import Combine

struct DecimalTextField: View {
    public let placeHolder: String
    @Binding var numericValue: Double
    private class DecimalTextFieldViewModel: ObservableObject {
        @Published var text = ""{
            didSet{
                DispatchQueue.main.async {
                    let substring = self.text.split(separator: Character("."), maxSplits: 2)
                    switch substring.count{
                        case 0:
                            if self.numericValue != 0{
                                self.numericValue = 0
                            }
                        case 1 :
                            var newValue: Double = 0
                            if let lastChar = substring[0].last{
                                if lastChar == Character("."){
                                    newValue = Double(String(substring[0]).dropLast()) ?? 0
                                }else{
                                    newValue = Double(String(substring[0])) ?? 0
                                }
                            }
                            self.numericValue = newValue
                        default:
                            self.numericValue =  Double(String("\(String(substring[0])).\(String(substring[1]))")) ?? 0
                    }
                }
            }
        }

        private var subCancellable: AnyCancellable!
        private var validCharSet = CharacterSet(charactersIn: "1234567890.")
        @Binding private var numericValue: Double{
            didSet{
                DispatchQueue.main.async {
                    if String(self.numericValue) != self.text {
                        self.text = String(self.numericValue)
                    }
                }
            }
        }
        init(numericValue: Binding<Double>, text: String) {
            self.text = text
            self._numericValue = numericValue
            subCancellable = $text.sink { val in
                //check if the new string contains any invalid characters
                if val.rangeOfCharacter(from: self.validCharSet.inverted) != nil {
                    //clean the string (do this on the main thread to avoid overlapping with the current ContentView update cycle)
                    DispatchQueue.main.async {
                        self.text = String(self.text.unicodeScalars.filter {
                            self.validCharSet.contains($0)
                        })
                    }
                }
            }
        }

        deinit {
            subCancellable.cancel()
        }
    }

    @ObservedObject private var viewModel: DecimalTextFieldViewModel

    init(placeHolder: String = "", numericValue: Binding<Double>){
        self._numericValue = numericValue
        self.placeHolder = placeHolder
        self.viewModel  = DecimalTextFieldViewModel(numericValue: self._numericValue, text: numericValue.wrappedValue == Double.zero ? "" : String(numericValue.wrappedValue))

    }
    var body: some View {
        TextField(placeHolder, text: $viewModel.text)
            .keyboardType(.decimalPad)
    }
}

struct testView: View{
    @State var numeric: Double = 0
    var body: some View{
        return VStack(alignment: .center){
            Text("input: \(String(numeric))")
            DecimalTextField(placeHolder: "123", numericValue: $numeric)
        }
    }
}

struct decimalTextField_Previews: PreviewProvider {
    static var previews: some View {
        testView()
    }
}

避免在键入时丢失小数点和尾随 0 的唯一方法是在数字字段的调用中跟踪字符串的整数和小数位,这意味着将数字精度值保留为超级视图状态的一部分。看这个要点使用此技术的全功能(Swift 5)视图。要了解如果不在超级视图中保留数字精度会发生什么,请比较下面预览中的第一个和第二个字段的行为:第一个字段将按预期处理输入,第二个字段将在以下情况下立即删除任何尾随的 .0值发生变化。

Screen grab of control in use

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NumberField 或如何让 TextField 输入 Double、Float 或其他带点的数字 的相关文章

  • 我如何确定视图在 SwiftUI 中的最后一行代码之前完全渲染?

    我有一些代码 它们必须在视图完全渲染和绘制后被触发 因为我们知道视图的 onAppear 或 onChange 它们对于了解视图是否已出现或正在更改很有用 但它们是确保视图已 100 渲染没有用 例如 如果我们在视图中获得 ForEach
  • SwiftUI - 方向更改后,NavigationView 标题和后退按钮被夹在状态栏下

    每当我将设备旋转到横向并再次返回时 顶部NavigationView 包括标题和后退按钮 被剪切在状态栏下方 最小可重现示例 struct ContentView View var body some View NavigationView
  • SwiftUI 检测按下删除按钮

    我正在使用 SwiftUI 但我正在编写自己的自定义文本掩码 但当用户按 删除 键时我需要删除 我正在使用onChange方法 但它不检测何时按下特殊键 目前我正在使用 TextField self placeholder text sel
  • SwiftUI withAnimation 完成回调

    我有一个基于某种状态的 swiftUI 动画 withAnimation linear duration 0 1 self someState newState 上述动画完成时是否会触发任何回调 如果有关于如何在 SwiftUI 中使用完成
  • 如何按日期正确对从 CoreData 获取的列表进行分组?

    为了简单起见 假设我想创建一个简单的待办事项应用程序 我的 xcdatamodeld 中有一个实体 Todo 其属性id title and date 以及以下 swiftui 视图 如图所示的示例 import SwiftUI struc
  • 如何在 SwiftUI 中管理 AVPlayer 状态

    我有 SwiftUI 中的 URL 列表 当我点击某个项目时 我会呈现一个全屏视频播放器 我有一个 EnvironmentObject它处理一些查看器选项 例如 是否显示时间码 我还有一个显示和隐藏时间码的切换开关 我只在本例中包含了该切换
  • 按下后退按钮时 SwiftUI 工具栏项目被剪裁

    我在 SwiftUI 中遇到了一种奇怪的行为 我似乎无法解决它 鉴于以下简单的示例应用程序 我遇到了这种行为 工具栏项目在初始运行时正确呈现 但导航离开并返回它会被剪切 重新创建此示例代码 内容视图 swift import SwiftUI
  • FocusState Textfield 在工具栏 ToolbarItem 中不起作用

    让我解释一下 我有一个带有 SearchBarView 的父视图 我正在传递这样的焦点状态绑定 SearchBarView searchText object searchQuery searching object searching f
  • 工作表关闭后 SwiftUI 导航栏项目框架未对齐

    在 SwiftUI 中关闭工作表后 导航栏按钮不可点击 以下是重现该问题的步骤 出示一张单子 将应用程序移至后台一小段时间 2 秒 恢复应用程序并向下滑动关闭工作表 现在导航栏按钮框架未对齐 点击的工作框架与按钮的可见框架不同 这在 iOS
  • 如何将图像转换为 UIImage?

    如何转换 SwiftUIImage to a UIImage let image Image systemName circle fill let UIImage image as UIImage 没有直接的方法将 Image 转换为 UI
  • 在 SwiftUI 中,如何执行手势但将手势转发到其后面的视图?

    我正在创建一个工具提示系统 如果用户触摸工具提示之外的任何地方 我想关闭工具提示 我希望这样在工具提示之外的触摸既可以消除工具提示 又可以激活用户点击的任何控件 因此 您可以打开一个工具提示 然后仍然单击工具提示外部的按钮 并在第一次点击时
  • SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中不会更新

    我知道 这是 无法在 iOS XX 中工作 问题之一 但我完全陷入困境 所以我有一个ObservableObject继承自的类NSObject 因为我需要听委托方法UISearchResultsUpdating class SearchBa
  • Javafx 从 TextField 获取输入

    这是我当前的代码 它所做的只是为我制作的计算器设置一个 GUI 界面 我希望用户输入两个值 然后当按下 Sum 按钮时 它将两个值加在一起并将其显示在 Sum 文本字段中 我正在尝试使用 JavaFX 如果您能提供一些帮助 我将不胜感激 i
  • 调用 SwiftUI 中位置 #11、#12 处的额外参数 [重复]

    这个问题在这里已经有答案了 我在 SwiftUI 中的切换开关上不断收到 调用中位置 11 12 处有额外参数 错误 我见过其他人有 调用中的额外参数 错误 但答案似乎没有帮助 另外 我的错误是 位置 11 12 我还没有看到其他人发生这种
  • 使用 Swift(使用 SwiftJWT)和 REST API 连接到 Apple Store Connect - 失败并出现 401

    我正在尝试通过他们的 REST API 连接到 Apple Store Connect 虽然这在几天前有效 但我无法弄清楚为什么它停止工作 现在我无法通过身份验证 即我发出的服务器响应的每个请求都是 401 我是否遗漏了什么 我做什么 生成
  • 如何使用 SwiftUI 创建自定义滑块?

    我可以使用 SwiftUI 创建滑块 但无法更改滑块的样式 如下图所示 问题 我无法在 SwiftUI 中找到任何选项来更改滑块样式 注意 我想仅使用 SwiftUI 创建它 我已经在 Swift 中使用 创建了这个滑块 https git
  • SwiftUI:为表单中的单元格添加动画

    我正在尝试动画化我的Form或者更确切地说是其中的细胞 我的问题是 下面的代码给了我一个很好的插入动画 但是对于删除 单元格在看起来很丑陋的延迟后突然被删除 import SwiftUI struct ContentView View St
  • 将 TextField 下划线颜色更改为渐变

    我可以更改轮廓颜色TextField s使用以下代码将颜色更改为纯色 TextField decoration InputDecoration focusedBorder UnderlineInputBorder borderSide Bo
  • SwiftUI 上带有 TextField 的可删除表

    环境 Xcode 11 2 1 11B500 Problem 为了在 SwiftUI 中实现带有 TextField 的可编辑表格 我使用了ForEach 0
  • Swift UI 导出画布内容

    我有一个画布 用户可以在上面画东西 我想导出用户在画布上绘制的任何内容 并且我正在使用以下扩展从视图中获取图像 extension View func snapshot gt UIImage let controller UIHosting

随机推荐

  • Bot 框架 - IDialogStack.PollAsync 在 3.5.0 后已弃用

    我正在查看 Bot 构建器示例存储库中的 core CreateNewConversation 示例 https github com Microsoft BotBuilder Samples IDialogStack 上有一个名为 Pol
  • 如何在 php 中循环访问一组 GET 值

    我正在制作一个简单的在线商店之类的程序 您建议我做什么 以便我可以循环遍历我在程序中所做的输入 我仍在使用 get 以便我可以看到数据的样子 我将更改它以稍后发布 当我承诺购买购物车中添加的所有产品时 网址如下所示 http localho
  • System.MissingMethodException:反序列化 json 数组时出错

    我在反序列化 jsonString 时遇到错误 错误是Type oodleListingsUser is not supported for deserialization of an array 我的反序列化代码是 string json
  • 将 VSCode 安装到特定文件夹中

    我刚刚下载了 Visual Studio Code 应用程序https code visualstudio com 当我尝试安装它时 它只是自行安装 没有更改安装路径的选项 我有一个外部硬盘驱动器 我希望在其中放置 IDE 而不是本地硬盘驱
  • 如果移除 DOM 元素,其侦听器是否也会从内存中移除?

    如果 DOM 元素被删除 它的监听器是否也会从内存中删除 现代浏览器 纯 JavaScript 如果被删除的 DOM 元素是无引用的 没有引用指向它 那么yes 元素本身由垃圾收集器以及与其关联的任何事件处理程序 侦听器拾取 var a d
  • Selenium WebDriver 将 Firefox 路径更改为 Tor

    我正在尝试更改 ruby 中的网络驱动程序以打开 Tor 浏览器而不是默认的 Firefox 浏览器 我正在使用以下代码 并且在运行此代码之前打开了 Tor 浏览器 path C Users Bonnnie Downloads Tor Br
  • 是否可以使用 Omnifaces #{of:setToList} 创建可编辑数据表

    我正在尝试创建一个可编辑的数据表 其值为java util Set 但在 JSF 2 0 和 2 1 中这是不可能的 如中所述在 Datatable JSF 中显示 Set 集合中的对象不起作用 到目前为止 作为解决方案 所有集都转换为ja
  • 我的 UIButton 的位置在所有模拟器中都不同

    我在一个项目下 我使用代码 不是通过故事板 在视图控制器的底部创建了一个 uibutton 但是当我运行我的应用程序时 我的 uibutton 放置在不同的位置 例如在 iphone 5 6 模拟器中某个位置 在 4s 中 ipad 模拟器
  • AngularJS 错误:指令“XXXXXX”的模板必须只有一个根元素

    这是后续这个问题 我正在尝试构建和 HTML table 与多个 tr 行 我希望其中一些行由我的指令呈现myDirectiveA以及其他由我的指令 myDirectiveB 呈现的内容 您可以在下面看到我的文件的样子 如果只有一个 一切正
  • Android,如何创建选项菜单

    在这里 我尝试制作选项菜单 但菜单没有显示在屏幕上 所以请指导我哪里做错了 菜单测试 java public class MenuTest extends Activity Override public boolean onCreateO
  • 给定当前日期和周开始,获取周开始和结束日期

    如果可能的话 我更喜欢针对以下场景的 joda 或非 joda 解决方案 假设我的一周从 02 05 2012 开始 并且给定的当前日期是 02 22 2011 我需要计算给定当前日期的周开始日期和结束日期 所以我的解决方案应该让一周从 0
  • ASP.Net 按钮单击事件未触发

    这或许与这个问题 但我有更多的信息 最近 在使用 Linq 编写了一些新代码后 我将 ASP Net 应用程序更新到了 NET 3 5 现在我的页面间歇性地停止触发事件处理程序 我将范围缩小到带有 Ajax 的页面 并且我认为是 Scrip
  • C 编译错误:“可变大小的对象可能未初始化”

    为什么我使用以下代码收到错误 可变大小的对象可能未初始化 int boardAux length length 0 我假设您正在使用 C99 编译器 带有支持动态大小的数组 您的代码中的问题是 当编译器看到您的变量声明时 它无法知道数组中有
  • ASP.Net Identity 注销所有会话

    如何使用 ASP NET Identity 注销所有会话 假设您使用同一用户从两个不同的浏览器登录 当用户从一个浏览器注销时 另一个浏览器的会话也应该失效 我需要这个来使用户在更改密码时的所有会话无效 您可以使用以下代码使用 ASP Net
  • 在 Nexus 中部署工件时出错

    我在 Nexus 服务器中部署自己的存储库中的工件时遇到错误 无法部署工件 无法传输工件 无法传输文件 http my artifact 返回代码为 400 我让 Nexus 与一个自定义存储库 my repo 一起运行 并使用下一个 Ma
  • 在作业中进行大量选择后,Spring 批处理内存不足

    我的工作遇到了问题 我正在尝试从数据库读取记录并写入txt 文件 数据库包含 1 800 000 条记录 有 149 列 问题是 select 位于 jobConfig xml 中的 bean mysqlItemReader 中 但是 我认
  • spring MVC POST 表单的大小限制?

    我有一个表格
  • 将存储库公开为 IQueryable

    我想将存储库公开为 IQueryable 类型 该存储库使用 Linq to NHibernate 与数据库进行通信 谁能指出我的示例实现吗 例如 我的存储库上相应的 GetEnumerator 实现是什么样子 Edit 这样的事情合适吗
  • 使用passport.js在node.js中进行身份验证后重定向到上一页

    我正在尝试使用node js express 和passport js 建立登录机制 登录本身工作得很好 会话也用 redis 很好地存储 但在提示用户进行身份验证之前将用户重定向到他开始的位置时确实遇到了一些麻烦 例如用户点击链接http
  • NumberField 或如何让 TextField 输入 Double、Float 或其他带点的数字

    根据评论这个问题我做了一个自定义的 SwiftUIView基于一个TextField 它使用数字键盘 只能输入数字和点 只能输入一个点 点 并且可以通过Bindable Double State价值通过View用于输入 但有一个错误 当您删