SwiftUI and WidgetKit: Getting AM and PM to wrap to a second line

69 Views Asked by At

Working in WidgetKit on the watch, I can't figure out how to style this text so that it looks correct. The problem is that, in locations where Am/Pm time styles are appropriate, the system only wraps the M to the next line, where I would like both AM and PM to wrap to the second line. In locations where they use a 24 hour clock, there should be no AM and PM. How can I achieve this?

static let sleepTimeFormat: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .none
        formatter.timeStyle = .short
        return formatter
    }()

    Text("\(targetBedTime, formatter: Self.sleepTimeFormat)")
        .font(.system(size: 14))
        .fontWeight(.bold)

enter image description here

1

There are 1 best solutions below

0
arsenius On BEST ANSWER

You can use ViewThatFits plus replace spaces with newlines to make this work.

let timeString = Self.sleepTimeFormat.string(from: .now)
ViewThatFits {
    Text(timeString).lineLimit(1)
    Text(timeString.replaceCharacters(from: .whitespaces, with: "\n")) // The formatter doesn't use a regular " "
}
.font(.system(size: 14))
.fontWeight(.bold)
.frame(width: 50) // Ensure second option gets displayed

// Convenience method 
extension String {
    func replaceCharacters(from characterSet: CharacterSet, with replacementString: String = "") -> String {
        self.components(separatedBy: characterSet).joined(separator: replacementString)
    }
}

And the result:

Broken across two lines