带有文字的文字。

发布于 2025-02-01 20:48:12 字数 3360 浏览 3 评论 0原文

我想创建一个由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:

enter image description here

A preview of rendering within complication:

CLKComplicationTemplateGraphicExtraLargeCircularView(
    ExtraLargeStack()
)
.previewContext(faceColor: .multicolor)

enter image description here


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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日浅笑〃 2025-02-08 20:48:12

因此,我弄清楚了对齐text(date(),样式:.timer) is的问题。计时器格式从小时开始。该文档以此为例:2:59 36:59:01。看来.timer保留所需的所有可能空间,然后在该可能的空间上格式化,而不是实际使用的空间。即使您的目标是5分钟的倒计时计时器,似乎也没有任何改变此行为的方法。

我认为您需要考虑轻微的UI更改。我确实发现您可以通过使用.timer将显示的文本的对齐方式通过.multilineTextAlignment()进行。你可以做。以下代码证明了这一点:

struct ExtraLargeStack: View {
    var body: some View {
        // I removed (alignment: .center) as it is redundant. VStacks default to center
        VStack {
            // I put the negative spacing to tighten the T: with the timer
            VStack(spacing: -6) {
                Text("T:")
                    .foregroundColor(.accentColor)
                
                Text(Date(), style: .timer)
                    // If you center with .multilineTextAlignment the timer
                    // will be centered
                    .multilineTextAlignment(.center)
                    .complicationForeground()
            }
            
            HStack {
                 HStack {
                    Text(Date(), style: .timer)
                        .multilineTextAlignment(.center)
                        .complicationForeground()
                        .overlay(
                            Text("T:")
                                .foregroundColor(.accentColor)
                                // This offset would need to be computed
                                .offset(x: -30, y: 0)
                        )
                }
            }
        }
        .font(.system(size: 18, weight: .regular))
    }
}

我将第二个计时器作为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:

struct ExtraLargeStack: View {
    var body: some View {
        // I removed (alignment: .center) as it is redundant. VStacks default to center
        VStack {
            // I put the negative spacing to tighten the T: with the timer
            VStack(spacing: -6) {
                Text("T:")
                    .foregroundColor(.accentColor)
                
                Text(Date(), style: .timer)
                    // If you center with .multilineTextAlignment the timer
                    // will be centered
                    .multilineTextAlignment(.center)
                    .complicationForeground()
            }
            
            HStack {
                 HStack {
                    Text(Date(), style: .timer)
                        .multilineTextAlignment(.center)
                        .complicationForeground()
                        .overlay(
                            Text("T:")
                                .foregroundColor(.accentColor)
                                // This offset would need to be computed
                                .offset(x: -30, y: 0)
                        )
                }
            }
        }
        .font(.system(size: 18, weight: .regular))
    }
}

I left the second timer as an HStack, but I put your Text("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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文