MeasurementFormatter для отображения футов и дюймов
Я играл с MeasurementFormatter
чтобы попытаться отобразить имперские длины как 10"6'
или же 10 ft 6 in
безуспешно. LengthFormatter
делает это правильно, когда isForPersonHeightUse
установлен в true
, но он плохо адаптируется к локали пользователя (т. е. в странах, где длина измеряется в метрической системе, за исключением случаев, когда речь идет о высоте). Есть ли способ заставить это поведение в форматере?
РЕДАКТИРОВАТЬ Этот вопрос, чтобы определить, как выбрать единицы измерения. Я могу выбрать футы или дюймы, но хочу отображать дробные футы в дюймах, например: 6'3"вместо 6.25 футов.
3 ответа
public struct LengthFormatters {
public static let imperialLengthFormatter: LengthFormatter = {
let formatter = LengthFormatter()
formatter.isForPersonHeightUse = true
return formatter
}()
}
extension Measurement where UnitType : UnitLength {
var heightOnFeetsAndInches: String? {
guard let measurement = self as? Measurement<UnitLength> else {
return nil
}
let meters = measurement.converted(to: .meters).value
LengthFormatters.imperialLengthFormatter.string(fromMeters: meters)
}
}
Пример использования:
let a = Measurement(value: 6.34, unit: UnitLength.feet)
print(a.heightOnFeetsAndInches ?? "")
let b = Measurement(value: 1.5, unit: UnitLength.feet)
print(b.heightOnFeetsAndInches ?? "")
Распечатает:
6 ft, 4.08 in
1 ft, 6 in
Как отображать футы и дюймы в SwiftUI
На случай, если кто-то придет сюда в поисках ответа SwiftUI.
struct MeasurementTestView: View {
@State private var height = Measurement(value: 68, unit: UnitLength.inches)
var body: some View {
VStack {
Text(height, format: .measurement(width: .narrow, usage: .personHeight))
Text(height, format: .measurement(width: .abbreviated, usage: .personHeight))
Text(height, format: .measurement(width: .wide, usage: .personHeight))
}
.font(.title)
}
}
Результат
Я изменил (упрощенный) ответ @maslovsa, чтобы удовлетворить мои потребности. У меня есть объект Core Data под названием "Пациент". У него есть параметр высоты в дюймах, который является Int64
, Мне нужна строка, которую я показываю пользователю, так что вот мое свойство объекта пациента для этого:
var heightInFeetString : String {
let measurement = Measurement(value: Double(self.height) / 12.0, unit: UnitLength.feet)
let meters = measurement.converted(to: .meters).value
return LengthFormatter.imperialLengthFormatter.string(fromMeters: meters)
}
Конечно, мне пришлось реализовать imperialLengthFormatter
но я сделал это как продолжение LengthFormatter
Сам, вот так:
extension LengthFormatter {
public static let imperialLengthFormatter: LengthFormatter = {
let formatter = LengthFormatter()
formatter.isForPersonHeightUse = true
return formatter
}()
}
Это на самом деле не снижает производительность, как это предлагается в комментариях к ответу @maslova. Поскольку свойство является статическим, оно инициализируется только один раз.
// When creating the Patient object
let patient = Patient(...) // Create in maanged object context
patient.height = 71
// Later displays in a collection view cell in a view controller
cell.heightLabel.Text = patient.heightInFeetString
Отображает это в ячейке моей таблицы:
5 футов, 11 дюймов