#swift #swiftui
Вопрос:
В SwiftUI я могу использовать интерполяцию строк с параметром форматирования. Это работает в нескольких местах, например:
struct ContentView: View {
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}()
let currentDate = Date()
@State var userInput = ""
@State var selection = ""
var body: some View {
Form {
Text("This is a date: (currentDate, formatter: Self.dateFormatter)")
Picker("This is also a date: (currentDate, formatter: Self.dateFormatter)",
selection: self.$selection) {
Text("Dummy")
}
}
}
}
Этот способ интерполяции строк, по-видимому, определен в SwiftUI, потому что, если я «перейду к определению» в Xcode, появятся следующие строки:
public mutating func appendInterpolation<Subject>(_ subject: Subject, formatter: Formatter? = nil) where Subject : ReferenceConvertible
public mutating func appendInterpolation<Subject>(_ subject: Subject, formatter: Formatter? = nil) where Subject : NSObject
Когда я пытаюсь использовать эту форму интерполяции строк на игровой площадке, она завершается ошибкой:
import SwiftUI
import Foundation
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}()
let date = Date()
print("Current date: (date, formatter: dateFormatter)")
Вышеприведенная игровая площадка завершается со следующей ошибкой:
error: StringInterpolationWithFormatter.playground:12:41: error: extra argument 'formatter' in call
print("Current date: (date, formatter: dateFormatter)")
^~~~~~~~~~~~~
Почему?
Ответ №1:
Вы можете использовать formatter:
аргумент в строковой интерполяции с Text
, потому что Text
инициализатор принимает a LocalizedStringKey
, а не a String
.
LocalizedStringKey
определил некоторые специальные функции интерполяции строк с appendInterpolation
показанными вами перегрузками (in LocalizedStringKey.StringInterpolation
), поэтому вы можете использовать formatter:
аргумент с ним.
Однако в инструкции print вы просто печатаете строку, и используется строка DefaultStringInterpolation
, у которой нет appendInterpolation
перегрузки, которая принимает formatter:
аргумент.
Просто создайте расширение DefaultStringInterpolation
, чтобы добавить эту новую интерполяцию строк, если хотите:
extension DefaultStringInterpolation {
// signature copied from LocalizedStringKey.StringInterpolation
mutating func appendInterpolation<Subject>(_ subject: Subject, formatter: Formatter) {
appendInterpolation(formatter.string(for: subject)!)
}
}
Ответ №2:
Сначала вам нужно создать свою собственную интерпретацию строк для строки. Подобный этому
extension String.StringInterpolation {
mutating func appendInterpolation(_ date: Date, formatter: DateFormatter) {
appendLiteral(formatter.string(from: date))
}
}
И теперь вы можете использовать
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}()
let date = Date()
print("Current date: (date, formatter: dateFormatter)")
Вы можете прочитать больше о интерполяции строк здесь