我目前有:
Text("Coronavirus Disease of 2019")
我希望它能够打印出2019年的COronaVirus Disease,并且一直没能成功地只让某些部分加粗。
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
简单说明一下,如果你需要将框架或填充修饰符应用于文本,则需要先对文本进行分组,然后再向组添加修饰符。
Group { Text("CO").bold() + Text("rona") + Text("VI").bold() + Text("rus Disease of 20") + Text("19").bold() }.frame(width: 100, height: 100).padding(.horizontal)
这类问题经常出现,对于没有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{}
对我来说是个秘密武器)
@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)
}
}
}
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])
}
}
Swift 5,iOS 13
本文介绍如何更改字符文本的颜色,但您同样可以使用该技术(位掩码)来使一些字符加粗、闪烁、动画等。
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
}
不仅可以使用加粗...
您可以使用AttributedString
将任何属性(加粗、颜色、字体等)应用于字符串的任何部分:
Text
现在支持Markdown,您还可以创建自定义属性:
你甚至可以远程获取已定义的属性,例如:
由于直到iOS 15都不支持Text
,所以您可以将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")
}
}
extension View {
func attributedBold(text: String, boldText: String,
font: Font = .largeTitle) -> AttributedString
{
var result = AttributedString(text)
result.font = font
if let range = result.range(of: boldText) {
result[range].font = font.bold()
}
result.foregroundColor = .white
return result
}
}
只需调用
Text(attributedBold(text: "Make me bold with attributed string",
boldText: "bold",
font: .title2))
**Bold**
和__Bold__
都可以产生粗体效果(而*Italic*
和_Italic_
则会呈现斜体)。 - JKvr