@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])
}
}
7条答案
按热度按时间bfnvny8b1#
iOS 15及更高版本(Swift 5.5及更高版本)
这是GitHub风格的markdown。AttributedString转换行内和块样式。SwiftUI渲染行内样式(但目前不渲染图像)。我们使用奇妙的cmark-gfm库解析markdown字符串。-SwiftUI Frameworks Engineer - developer.apple.com
查看更多信息:
什么是降价?
在要加粗的字符周围使用双星号()。
在要设置为斜体的字符周围使用下划线(_)。
字符串变量
使用
init(_ value: String)
从给定的字符串值创建本地化字符串键。
字符串插值
使用
init(_ value: String)
从给定的字符串值创建本地化字符串键。
属性化字符串
使用
init(_ attributedContent: AttributedString)
创建显示样式化属性内容的文本视图。
init(_ attributedContent: AttributedString)
-https://developer.apple.com6qqygrtg2#
如果你不需要翻译它这里是可能的快速变种
另一种方法是将NSAttributedString与
UILabel
的UIViewRepresentable
一起使用。qltillow3#
一个快速的注解只是为了补充Asperi的伟大答案,如果你需要应用框架或填充修饰符到你的文本,你需要先分组文本,然后添加你的修饰符到组。
uemypmqf4#
这个问题的味道突然出现了很多,对于一个没有Objective-C背景的Swift新手来说,解决方案出现得很勉强。上面的几个答案都很好,但总结一下这个问题的最佳解决方案,
(
Group{}
是我的秘密酱料)t5zmwmid5#
Swift 5、iOS 13操作系统
这篇文章是关于改变字符文本的颜色,但是你同样可以应用它使用的技术[位掩码]使一些字符加粗, Flink ,动画什么的?
https://medium.com/@marklucking/an-interesting-challenge-with-swiftui-9ebb26e77376
你需要关注的两个核心部分是...
这个用来掩盖文字。
fxnxkyjh6#
@mahan提出的解决方案很棒,但它有一个局限性,即它在iOS 15上运行良好,但在iOS 14上不是。
所以我认为对于那些需要支持iOS 14的人来说,这是一个更好的解决方案,解决方案是从这个网站复制的:https://www.avanderlee.com/swiftui/text-weight-combinations/
最终代码如下所示:
(you可以自定义字体,并在文本中有变量,例如:)
密码是:
jtw3ybtb7#
不仅大胆...
可以使用
AttributedString
将任何属性(粗体、颜色、字体等)应用于字符串的任何部分:iOS 15操作系统
Text
现在支持markdown,您还可以创建自定义属性:您甚至可以远程获取定义的属性,例如:
所有iOS版本都完全支持的后备功能!
由于
Text
不直接支持UILabel
(直到iOS 15),您可以将UILabel
带到那里,并根据自己的喜好进行修改:实施:
用法: