带有文字的文字。
我想创建一个由SwiftUI视图呈现的并发症,其中包含标签和计时器值。
我希望标签位于并发症背景层上,并且计时器值位于并发症前景层上,以便它们分开着色。
我希望这条文本由2个部分组成,以中心为中心。
问题是,当使用text.datestyle.timer时,文本在正常视图中的并发症与并发症中的行为不同。
在正常视图中,文本框架的行为就像其他任何文本一样,只能占用所需的空间。
当以复杂性显示时,文本框架会扩展以填充它可以填充的所有空间,并且内部的文本将对齐。
这使得我找不到将两个文本组为中心的方法。
我尝试使用无限间隔者的某种刺耳的方法来尝试从具有扩展框架的文本中窃取额外的空间。这可以使内容集中,但会导致文本截断。
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
HStack {
Spacer()
.frame(maxWidth: .infinity)
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
Spacer()
.frame(maxWidth: .infinity)
}
正常预览:
复杂性中渲染的预览:
CLKComplicationTemplateGraphicExtraLargeCircularView(
ExtraLargeStack()
)
.previewContext(faceColor: .multicolor)
编辑以显示完整代码
import ClockKit
import SwiftUI
struct ExtraLargeStack: View {
var body: some View {
VStack(alignment: .center) {
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
HStack {
Spacer()
.frame(maxWidth: .infinity)
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
Spacer()
.frame(maxWidth: .infinity)
}
}
.font(.system(size: 18, weight: .regular))
.lineLimit(1)
}
}
struct ExtraLargeStack_Previews: PreviewProvider {
static var previews: some View {
/// Preview normal view
// ExtraLargeStack()
/// Preview as Complication
CLKComplicationTemplateGraphicExtraLargeCircularView(
ExtraLargeStack()
)
.previewContext(faceColor: .multicolor)
}
}
编辑:另一部分 基于@YRB的建议的解决方案
,覆盖层提供了一个部分解决方案,对于我的用例来说可能足够好。
以下内容并未完全居中2部分,但是非常接近。
HStack {
// Use placeholder text to create a view with the appropriate size for _most_ timer values that I need to support
Text("L: 00:00 ").hidden()
}
.overlay(
// overlay the real content, which is constrained to the frame created by the hidden placeholder.
HStack(spacing: 5) {
Text("L:")
.foregroundColor(.accentColor)
Text(Date() - 3599, style: .timer)
.complicationForeground()
}
)
I want to create a complication rendered by a SwiftUI View that contains a label and a timer value.
I want the label to be on the complication background layer, and the timer value to be on the complication foreground layer so that they get tinted separately.
I would like this line of text, comprised of 2 parts, to be centered.
The trouble is, when using Text.DateStyle.timer, the Text behaves differently within a complication vs in a normal view.
In a normal view the Text frame behaves as any other text, only taking the space it needs.
When displayed in a complication, the Text frame expands to fill all the space it can, and the text within is left aligned.
This makes it so I cannot find a way to center the group of 2 Texts.
I tried a somewhat hacky approach with infinite spacers to try to steal the extra space from the Text that has the expanding frame. This works to center the content, but it causes the Text to truncate.
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
HStack {
Spacer()
.frame(maxWidth: .infinity)
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
Spacer()
.frame(maxWidth: .infinity)
}
A normal preview:
A preview of rendering within complication:
CLKComplicationTemplateGraphicExtraLargeCircularView(
ExtraLargeStack()
)
.previewContext(faceColor: .multicolor)
Edit to show full code
import ClockKit
import SwiftUI
struct ExtraLargeStack: View {
var body: some View {
VStack(alignment: .center) {
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
HStack {
Spacer()
.frame(maxWidth: .infinity)
HStack {
Text("T:")
.foregroundColor(.accentColor)
Text(Date(), style: .timer)
.complicationForeground()
}
Spacer()
.frame(maxWidth: .infinity)
}
}
.font(.system(size: 18, weight: .regular))
.lineLimit(1)
}
}
struct ExtraLargeStack_Previews: PreviewProvider {
static var previews: some View {
/// Preview normal view
// ExtraLargeStack()
/// Preview as Complication
CLKComplicationTemplateGraphicExtraLargeCircularView(
ExtraLargeStack()
)
.previewContext(faceColor: .multicolor)
}
}
Edit: Another partial solution
Based on suggestions from @Yrb, an overlay provides a partial solution that may be good enough for my use case.
The following does not fully center the 2 part line, but it is pretty close.
HStack {
// Use placeholder text to create a view with the appropriate size for _most_ timer values that I need to support
Text("L: 00:00 ").hidden()
}
.overlay(
// overlay the real content, which is constrained to the frame created by the hidden placeholder.
HStack(spacing: 5) {
Text("L:")
.foregroundColor(.accentColor)
Text(Date() - 3599, style: .timer)
.complicationForeground()
}
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,我弄清楚了对齐
text(date(),样式:.timer)
is的问题。计时器格式从小时开始。该文档以此为例:2:59 36:59:01
。看来.timer
保留所需的所有可能空间,然后在该可能的空间上格式化,而不是实际使用的空间。即使您的目标是5分钟的倒计时计时器,似乎也没有任何改变此行为的方法。我认为您需要考虑轻微的UI更改。我确实发现您可以通过使用
.timer
将显示的文本
的对齐方式通过.multilineTextAlignment()
进行。你可以做。以下代码证明了这一点:我将第二个计时器作为
hstack
,但我将您的text(“ t”)
作为.overlay()
代码>带有.offset()
。我并不特别喜欢这种情况,因为如果您尝试在额外的时间单元中调整偏移量,那将是脆弱的,但是如果您的范围有限,则可能足够好。另外,如果您在计时器文本上使用.monoptaced
,则该计算应为线性量。So, I figured out what the issue with aligning
Text(Date(), style: .timer)
is. The timer format from hours on down. The document give this as an example:2:59 36:59:01
. It appears that.timer
reserves all of the possible space it needs and then is formatted on that possible space, not the space actually used. There does not appear to be any way to change this behavior, even if your goal is a 5 minute countdown timer.I think you need to consider slight UI change. I did find that you can change the alignment of the displayed
Text
with a.timer
by using.multilineTextAlignment()
, but that is about all you can do. The following code demonstrates this:I left the second timer as an
HStack
, but I put yourText("T")
as an.overlay()
with a.offset()
. I don't particularly like this as it will be fragile if you attempt to adjust the offset for the additional time units, but if you have a limited range, it may work well enough. Also, if you use.monospaced
on the timer text, the computation should be a linear amount.