【问题标题】:Change format of a textfield on the fly using RxSwift [closed]使用 RxSwift 动态更改文本字段的格式 [关闭]
【发布时间】:2019-09-16 21:56:16
【问题描述】:

我想给我的文本字段一个货币格式,所以当我输入时它看起来像:

$0.00
$0.09
$0.98
$9.87
98.76 美元

【问题讨论】:

  • 为什么需要 RxSwift 来格式化文本字段中的文本?有许多现有示例展示了如何在键入时设置文本字段的格式,包括货币。
  • @rmaddy 我发现的一些示例使用了诸如 textDidChange/textShouldChange 之类的通知,我只想让我的代码只包含 Rx 序列。
  • 这些不是通知。这些是委托方法。大不同。
  • 对不起,我很困惑,所以我的主要目标是不使用委托,因为我使用的是 Rx,我知道他们可以生活在同一个项目中

标签: ios swift rx-swift rx-cocoa


【解决方案1】:

所以我做的是:

ObservableType 的扩展,具有 2 个功能,一个用于转换为所需的格式,另一个用于读取值:

extension ObservableType where E == String {

    func currencyFormattedToValue() -> Observable<E> {
        return asObservable().flatMap { currencyString -> Observable<E> in
          let formatter = Constants.moneyFormatter
          let value = Double(truncating: formatter.number(from: currencyString) ?? 0.00).rounded(toPlaces: 2)
          return Observable.just("\(value)")
        }
    }

    func valueToCurrencyFormatted() -> Observable<E> {
        return asObservable().flatMap { valueString -> Observable<E> in
          let formatter = Constants.moneyFormatter
          var amountWithPrefix = valueString
          var number: NSNumber!

          let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
          amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, valueString.count), withTemplate: "")

          let double = (amountWithPrefix as NSString).doubleValue
          number = NSNumber(value: (double / 100))

          guard number != 0 as NSNumber else {
            return Observable.just("$0.00")
          }
          return Observable.just(formatter.string(from: number)!)
      }
  }
}

然后我像这样使用它们:

textField.rx.text
    .orEmpty
    .changed
    .valueToCurrencyFormatted()
    .bind(to: self.textField.rx.text)
    .disposed(by: disposeBag)

并读取值并将其绑定到主题:

textField.rx.text
  .orEmpty
  .currencyFormattedToValue()
  .bind(to: viewModel.amountValue)
  .disposed(by: disposeBag)

我的格式化程序:

class Constants {
  static var moneyFormatter:NumberFormatter {
    let formatter = NumberFormatter()
    formatter.numberStyle = .currencyAccounting
    formatter.currencySymbol = "$"
    formatter.maximumFractionDigits = 2
    formatter.minimumFractionDigits = 2

    return formatter
  }
}

我开放你的建议,谢谢!

【讨论】:

  • 您所拥有的一切都很好,只是每次用户更改任何值时它都会将光标推到文本字段的末尾。因此,例如,如果用户选择 . 左侧的数字并键入“25”,他们会期望看到“$25.00”,但他们会得到“$2.05”甚至可能是“$0.05”。要解决这个问题,请使用:gist.github.com/danielt1263/cacfd3f7cd55adfe4cedba990d751d38
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多