在SwiftUI中将部分文本加粗

nfeuvbwi  于 2023-02-21  发布在  Swift
关注(0)|答案(7)|浏览(164)

我想知道如何在SwiftUI中只将文本的部分加粗,而将其余部分保持为"常规"。
我目前有:

Text("Coronavirus Disease of 2019")

我想打印出CORONAViRUSD版本2019,但无法仅将某些部分加粗。

bfnvny8b

bfnvny8b1#

iOS 15及更高版本(Swift 5.5及更高版本)

    • SwiftUI**内置了对渲染Markdown的支持。

这是GitHub风格的markdown。AttributedString转换行内和块样式。SwiftUI渲染行内样式(但目前不渲染图像)。我们使用奇妙的cmark-gfm库解析markdown字符串。-SwiftUI Frameworks Engineer - developer.apple.com

查看更多信息:

什么是降价?
在要加粗的字符周围使用双星号()。

Text("**CO**rona**V**irus **D**isease of 20**19**")

在要设置为斜体的字符周围使用下划线(_)

Text("Is this text _emphasized_?")

字符串变量

使用init(_ value: String)
从给定的字符串值创建本地化字符串键。

let bold = "This text is **bold**"
Text(.init(bold))

字符串插值

使用init(_ value: String)
从给定的字符串值创建本地化字符串键。

let bold = "Bold"
Text(.init("This text is **\(bold)**"))

属性化字符串

使用init(_ attributedContent: AttributedString)
创建显示样式化属性内容的文本视图。

let markdownText = try! AttributedString(markdown: "This text is **bold**")
Text(markdownText)
    • 另见:**

init(_ attributedContent: AttributedString)-https://developer.apple.com

6qqygrtg

6qqygrtg2#

如果你不需要翻译它这里是可能的快速变种

Text("CO").bold() + Text("rona") + Text("VI").bold() + 
    Text("rus Disease of 20") + Text("19").bold()

另一种方法是将NSAttributedString与UILabelUIViewRepresentable一起使用。

qltillow

qltillow3#

一个快速的注解只是为了补充Asperi的伟大答案,如果你需要应用框架或填充修饰符到你的文本,你需要先分组文本,然后添加你的修饰符到组。

Group { Text("CO").bold() + Text("rona") + Text("VI").bold() + Text("rus Disease of 20") + Text("19").bold() }.frame(width: 100, height: 100).padding(.horizontal)
uemypmqf

uemypmqf4#

这个问题的味道突然出现了很多,对于一个没有Objective-C背景的Swift新手来说,解决方案出现得很勉强。上面的几个答案都很好,但总结一下这个问题的最佳解决方案,

Group {
    Text("CO").bold() +
    Text("rona") +
    Text("V").bold() +
    Text("irus ") +
    Text("D").bold() +
    Text("isease of 20") +
    Text("19").bold()
}
.font(.caption)
.frame(width: 300)

Group{}是我的秘密酱料)

t5zmwmid

t5zmwmid5#

Swift 5、iOS 13操作系统
这篇文章是关于改变字符文本的颜色,但是你同样可以应用它使用的技术[位掩码]使一些字符加粗, Flink ,动画什么的?
https://medium.com/@marklucking/an-interesting-challenge-with-swiftui-9ebb26e77376
你需要关注的两个核心部分是...

ForEach((0 ..< letter.count), id: \.self) { column in
          Text(letter[column])
            .foregroundColor(colorCode(gate: Int(self.gate), no: column) ? Color.black: Color.red)
            .font(Fonts.futuraCondensedMedium(size: fontSize))

        }

这个用来掩盖文字。

func colorCode(gate:Int, no:Int) -> Bool {

  let bgr = String(gate, radix:2).pad(with: "0", toLength: 16)
  let bcr = String(no, radix:2).pad(with: "0", toLength: 16)
  let binaryColumn = 1 << no - 1

  let value = UInt64(gate) & UInt64(binaryColumn)
  let vr = String(value, radix:2).pad(with: "0", toLength: 16)

  print("bg ",bgr," bc ",bcr,vr)
  return value > 0 ? true:false
}
fxnxkyjh

fxnxkyjh6#

@mahan提出的解决方案很棒,但它有一个局限性,即它在iOS 15上运行良好,但在iOS 14上不是。
所以我认为对于那些需要支持iOS 14的人来说,这是一个更好的解决方案,解决方案是从这个网站复制的:https://www.avanderlee.com/swiftui/text-weight-combinations/
最终代码如下所示:

@main
struct RichTextApp: App {
    var body: some Scene {
        WindowGroup {
            RichText("SwiftLee - A *weekly blog* about Swift, iOS and Xcode *Tips and Tricks*")
                .padding()
                .multilineTextAlignment(.center)
        }
    }
}

(you可以自定义字体,并在文本中有变量,例如:)

RichText(" ... *\(viewModel.title)* ...")

密码是:

import SwiftUI

struct RichText: View {

    struct Element: Identifiable {
        let id = UUID()
        let content: String
        let isBold: Bool

        init(content: String, isBold: Bool) {
            var content = content.trimmingCharacters(in: .whitespacesAndNewlines)

            if isBold {
                content = content.replacingOccurrences(of: "*", with: "")
            }

            self.content = content
            self.isBold = isBold
        }
    }

    let elements: [Element]

    init(_ content: String) {
        elements = content.parseRichTextElements()
    }

    var body: some View {
        var content = text(for: elements.first!)
        elements.dropFirst().forEach { (element) in
            content = content + self.text(for: element)
        }
        return content
    }
    
    private func text(for element: Element) -> Text {
        let postfix = shouldAddSpace(for: element) ? " " : ""
        if element.isBold {
            return Text(element.content + postfix)
                .fontWeight(.bold)
        } else {
            return Text(element.content + postfix)
        }
    }

    private func shouldAddSpace(for element: Element) -> Bool {
        return element.id != elements.last?.id
    }
    
}


extension String {

    /// Parses the input text and returns a collection of rich text elements.
    /// Currently supports asterisks only. E.g. "Save *everything* that *inspires* your ideas".
    ///
    /// - Returns: A collection of rich text elements.
    func parseRichTextElements() -> [RichText.Element] {
        let regex = try! NSRegularExpression(pattern: "\\*{1}(.*?)\\*{1}")
        let range = NSRange(location: 0, length: count)

        /// Find all the ranges that match the regex *CONTENT*.
        let matches: [NSTextCheckingResult] = regex.matches(in: self, options: [], range: range)
        let matchingRanges = matches.compactMap { Range<Int>($0.range) }

        var elements: [RichText.Element] = []

        // Add the first range which might be the complete content if no match was found.
        // This is the range up until the lowerbound of the first match.
        let firstRange = 0..<(matchingRanges.count == 0 ? count : matchingRanges[0].lowerBound)

        self[firstRange].components(separatedBy: " ").forEach { (word) in
            guard !word.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
            elements.append(RichText.Element(content: String(word), isBold: false))
        }

        // Create elements for the remaining words and ranges.
        for (index, matchingRange) in matchingRanges.enumerated() {
            let isLast = matchingRange == matchingRanges.last

            // Add an element for the matching range which should be bold.
            let matchContent = self[matchingRange]
            elements.append(RichText.Element(content: matchContent, isBold: true))

            // Add an element for the text in-between the current match and the next match.
            let endLocation = isLast ? count : matchingRanges[index + 1].lowerBound
            let range = matchingRange.upperBound..<endLocation
            self[range].components(separatedBy: " ").forEach { (word) in
                guard !word.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
                elements.append(RichText.Element(content: String(word), isBold: false))
            }
        }

        return elements
    }

    /// - Returns: A string subscript based on the given range.
    subscript(range: Range<Int>) -> String {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        let endIndex = index(self.startIndex, offsetBy: range.upperBound)
        return String(self[startIndex..<endIndex])
    }
}
jtw3ybtb

jtw3ybtb7#

不仅大胆...
可以使用AttributedString将任何属性(粗体、颜色、字体等)应用于字符串的任何部分:
iOS 15操作系统
Text现在支持markdown,您还可以创建自定义属性:

您甚至可以远程获取定义的属性,例如:

所有iOS版本都完全支持的后备功能!

由于Text不直接支持UILabel(直到iOS 15),您可以将UILabel带到那里,并根据自己的喜好进行修改:

实施:
struct UIKLabel: UIViewRepresentable {

    typealias TheUIView = UILabel
    fileprivate var configuration = { (view: TheUIView) in }

    func makeUIView(context: UIViewRepresentableContext<Self>) -> TheUIView { TheUIView() }
    func updateUIView(_ uiView: TheUIView, context: UIViewRepresentableContext<Self>) {
        configuration(uiView)
    }
}
用法:
var body: some View {
    UIKLabel {
        $0.attributedText = NSAttributedString(string: "HelloWorld")
    }
}

相关问题