具有交替行颜色的多行文本(日志视图)。如何跨行选择文本?

问题描述 投票:0回答:1

我有日志视图。 我想以交替的背景颜色显示日志行。 我想允许在整个日志视图中进行文本选择。这可以在单个

.textSelection(.enabled)
视图上使用
Text
来完成。

然而,问题是,为了获得交替的颜色,我将字符串分成几行,并以

ScrollView
(或
List
)显示它们。当我添加
.textSelection(.enabled)
时,我一次只能选择一行中的文本。 我怎样才能选择整个文本。

这是代码:

struct LogView: View {
    let lines: [String] = sampleText3.components(separatedBy: "\n")
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 0) {
                ForEach(lines.indices, id: \.self) { index in
                    HStack() {
                        Text(lines[index])
                            .foregroundColor(adaptiveLineColor(lines[index]))
                            .padding(.horizontal, 5)
                        Spacer()
                    }
                    .background(index % 2 == 0 ?  Color.gray.opacity(0.1) : Color.black.opacity(0.1))
                }
            }
            .textSelection(.enabled)
            .border(.gray.opacity(0.1),width: 1)
        }
        .padding()
    }
    
    func adaptiveLineColor(_ line: String) -> Color {
        enum Tag: String {
            case task = "[Task]"
            case info = "[info]"
            case warning = "[warning]"
            case error = "[error]"
        }
        // TODO: Use switch
        if line.hasPrefix(Tag.task.rawValue) {
            return .green
        }
        if line.hasPrefix(Tag.info.rawValue) {
            return .primary
        }
        if line.hasPrefix(Tag.warning.rawValue) {
            return .yellow
        }
        if line.hasPrefix(Tag.error.rawValue) {
            return .red
        }
        return .primary
    }
}

let sampleText3: String = """
[Task] Process started. 30. Sep 2023, 21:26:20
[info] input file /someFolder/someData
[warning] invalid metadata
[error] error -1234
"""

截图:

如果我将整个文本放在一个多行中

Text
textSelection
会按预期工作,但我不知道如何交替背景颜色。

我该如何解决这个问题?

我找到了这个问题,但是没有解决办法。

swiftui textselection swiftui-text
1个回答
0
投票

一个非常简单的解决方案(尽管这有点黑客)是绘制两次。首先将文本绘制为许多单独的

Text
,每个都有自己的背景和透明的前景。然后,将整个字符串绘制为单个
Text
作为叠加层。然后用户可以选择叠加。

ScrollView {
    let attrText = makeAttributedString(sampleText3) // add all the different foreground colors as an AttributedString

    VStack(alignment: .leading, spacing: 0) {
        // lay out the texts with transparent foreground and alternating backgrounds
        let invisibleTexts = lines.map { Text($0).foregroundColor(.clear) }
        ForEach(lines.indices, id: \.self) { index in
            HStack {
                invisibleTexts[index]
                    .padding(.horizontal, 5)
                Spacer()
            }
            .background(index % 2 == 0 ?  Color.gray.opacity(0.1) : Color.black.opacity(0.1))
        }
    }
    .overlay {
        // lay out the selectable text in the same way
        HStack {
            Text(attrText).textSelection(.enabled).padding(.horizontal, 5)
            Spacer()
        }
    }
    .border(.gray.opacity(0.1),width: 1)
}
© www.soinside.com 2019 - 2024. All rights reserved.