Ale*_*aev 22 ios swift widgetkit swiftui
.timer 文本样式将其扩展以填充宽度,而不是占用空间来容纳所包含的字符串。有办法改变这种行为吗?
\nText(entry.timeFinished, style: .timer).multilineTextAlignment(.leading).opacity(0.5).background(Color.red)\nRun Code Online (Sandbox Code Playgroud)\n\nText("3:41").opacity(0.5).background(Color.blue)\nRun Code Online (Sandbox Code Playgroud)\n\n整个视图:
\nstruct TimePieceWidgetEntryView: View {\n \n var entry: Provider.Entry\n \n var body: some View {\n VStack {\n Text("Timer \xe2\x8f\xb1")\n Text(Date().addingTimeInterval(600), style: .timer).opacity(0.5)\n }.font(.title.bold().monospacedDigit())\n .padding(5)\n .widgetURL(entry.url)\n }\n \n}\nRun Code Online (Sandbox Code Playgroud)\n
我对苹果如何构建实时活动和小部件的了解为零。我的猜测是小部件被渲染然后被缓存。这就是为什么标准计时器/发布器之类的东西不会更新 UI。我的猜测是,这些文本计时器填充了空间,以便 Apple 可以在缓存视图的顶部渲染标签,而无需在文本大小发生变化时从小部件中请求新的布局。我这样说是因为我认为容器的填充是一个功能而不是一个错误,所以它可能不会很快改变。
为了解决这个问题,我强制将文本视图的大小设置为应有的最大大小。仍然存在一些问题,但在大多数情况下,这个解决方案看起来不错。
struct TextTimer: View {
// Return the largest width string for a time interval
private static func maxStringFor(_ time: TimeInterval) -> String {
if time < 600 { // 9:99
return "0:00"
}
if time < 3600 { // 59:59
return "00:00"
}
if time < 36000 { // 9:59:59
return "0:00:00"
}
return "00:00:00"// 99:59:59
}
init(_ date: Date, font: UIFont, width: CGFloat? = nil) {
self.date = date
self.font = font
if let width {
self.width = width
} else {
let fontAttributes = [NSAttributedString.Key.font: font]
let time = date.timeIntervalSinceNow
let maxString = Self.maxStringFor(time)
self.width = (maxString as NSString).size(withAttributes: fontAttributes).width
}
}
let date: Date
let font: UIFont
let width: CGFloat
var body: some View {
Text(timerInterval: Date.now...date)
.font(Font(font))
.frame(width: width > 0 ? width : nil)
.minimumScaleFactor(0.5)
.lineLimit(1)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1353 次 |
| 最近记录: |