- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的屏幕上有一些文字:
Text("someText1")
是否可以在不创建大量文本项的情况下突出显示/选择部分文本
我是说
Text("som") + Text("eTex").foregroundColor(.red) + Text("t1")
这不是我的解决方案
最好有某种修饰符以某种方式突出显示文本的一部分。类似于:
Text("someText1").modifier(.highlight(text:"eTex"))
这可能吗? (我的意思是没有创建很多 View )
最佳答案
一旦创建文本,就无法再打开它。您的示例会产生本地化问题。 someText1
实际上不是要打印的字符串。它是字符串的本地化键。默认的本地化字符串恰好是键,所以它可以工作。您尝试搜索 eTex
当你本地化时会悄然中断。所以这不是一个好的通用接口(interface)。
即便如此,构建解决方案还是非常有启发性的,并且可能对特定情况有用。
基本目标是将样式视为应用于范围的属性。这正是 NSAttributedString 为我们提供的功能,包括合并和分割范围以管理多个重叠属性的能力。 NSAttributedString 对 Swift 不是特别友好,因此从头开始重新实现它可能会有一些值(value),但相反,我只是将其隐藏为实现细节。
因此,TextStyle 将是一个 NSAttributedString.Key 和一个将文本转换为另一个文本的函数。
public struct TextStyle {
// This type is opaque because it exposes NSAttributedString details and
// requires unique keys. It can be extended by public static methods.
// Properties are internal to be accessed by StyledText
internal let key: NSAttributedString.Key
internal let apply: (Text) -> Text
private init(key: NSAttributedString.Key, apply: @escaping (Text) -> Text) {
self.key = key
self.apply = apply
}
}
TextStyle 不透明。为了构建它,我们公开了一些扩展,例如:
// Public methods for building styles
public extension TextStyle {
static func foregroundColor(_ color: Color) -> TextStyle {
TextStyle(key: .init("TextStyleForegroundColor"), apply: { $0.foregroundColor(color) })
}
static func bold() -> TextStyle {
TextStyle(key: .init("TextStyleBold"), apply: { $0.bold() })
}
}
这里值得注意的是 NSAttributedString 只是“由范围内的属性注释的字符串”。它不是“样式化的字符串”。我们可以编写我们想要的任何属性键和值。因此,这些属性故意与 Cocoa 用于格式化的属性不同。
接下来,我们创建 StyledText 本身。我首先关注这种类型的“模型”部分(稍后我们会将其设为 View )。
public struct StyledText {
// This is a value type. Don't be tempted to use NSMutableAttributedString here unless
// you also implement copy-on-write.
private var attributedString: NSAttributedString
private init(attributedString: NSAttributedString) {
self.attributedString = attributedString
}
public func style<S>(_ style: TextStyle,
ranges: (String) -> S) -> StyledText
where S: Sequence, S.Element == Range<String.Index>?
{
// Remember this is a value type. If you want to avoid this copy,
// then you need to implement copy-on-write.
let newAttributedString = NSMutableAttributedString(attributedString: attributedString)
for range in ranges(attributedString.string).compactMap({ $0 }) {
let nsRange = NSRange(range, in: attributedString.string)
newAttributedString.addAttribute(style.key, value: style, range: nsRange)
}
return StyledText(attributedString: newAttributedString)
}
}
它只是 NSAttributedString 的包装器,以及通过将 TextStyle 应用于范围来创建新 StyledText 的方法。一些要点:
调用 style
不会改变现有对象。如果是这样,你就不能做像 return StyledText("text").apply(.bold())
这样的事情。您会收到一个错误,表明该值是不可变的。
范围是很棘手的事情。 NSAttributedString 使用 NSRange,并且具有与 String 不同的索引概念。 NSAttributedStrings 的长度可以与底层字符串不同,因为它们组成字符的方式不同。
您无法安全地使用 String.Index
从一个字符串并将其应用到另一个字符串,即使这两个字符串看起来相同。这就是为什么该系统采用闭包来创建范围而不是采用范围本身。 attributedString.string
与传入的字符串不完全相同。如果调用者想要传递 Range<String.Index>
,使用与 TextStyle 使用的字符串完全相同的字符串来构造它是至关重要的。通过使用闭包最容易确保这一点,并避免很多极端情况。
默认style
接口(interface)处理一系列范围以实现灵 active 。但在大多数情况下,您可能只会传递一个范围,因此最好有一种方便的方法来实现这一点,并且对于您想要整个字符串的情况:
public extension StyledText {
// A convenience extension to apply to a single range.
func style(_ style: TextStyle,
range: (String) -> Range<String.Index> = { $0.startIndex..<$0.endIndex }) -> StyledText {
self.style(style, ranges: { [range($0)] })
}
}
现在,用于创建 StyledText 的公共(public)接口(interface):
extension StyledText {
public init(verbatim content: String, styles: [TextStyle] = []) {
let attributes = styles.reduce(into: [:]) { result, style in
result[style.key] = style
}
attributedString = NSMutableAttributedString(string: content, attributes: attributes)
}
}
注意 verbatim
这里。此 StyledText 不支持本地化。可以想象,通过工作可以做到这一点,但还需要更多的思考。
最后,我们可以将其设为一个 View ,方法是为每个具有相同属性的子字符串创建一个文本,将所有样式应用于该文本,然后使用 +
将所有文本合并为一个文本。 。为了方便起见,文本是直接公开的,因此您可以将其与标准 View 结合起来。
extension StyledText: View {
public var body: some View { text() }
public func text() -> Text {
var text: Text = Text(verbatim: "")
attributedString
.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length),
options: [])
{ (attributes, range, _) in
let string = attributedString.attributedSubstring(from: range).string
let modifiers = attributes.values.map { $0 as! TextStyle }
text = text + modifiers.reduce(Text(verbatim: string)) { segment, style in
style.apply(segment)
}
}
return text
}
}
就是这样。使用它看起来像这样:
// An internal convenience extension that could be defined outside this pacakge.
// This wouldn't be a general-purpose way to highlight, but shows how a caller could create
// their own extensions
extension TextStyle {
static func highlight() -> TextStyle { .foregroundColor(.red) }
}
struct ContentView: View {
var body: some View {
StyledText(verbatim: "👩👩👦someText1")
.style(.highlight(), ranges: { [$0.range(of: "eTex"), $0.range(of: "1")] })
.style(.bold())
}
}
您也可以将 UILabel 包装在 UIViewRepresentable 中,并使用 attributedText
。但这是作弊。 :D
关于SwiftUI:是否存在修饰符来突出显示 Text() View 的子字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59426359/
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[text(text - text text) !text]。这里的文本实际上可以是任何字符。并且间距很重要。文本将如图所示列出。 我已经
这个问题在这里已经有了答案: Remove duplicate commas and extra commas at start/end with RegExp in Javascript, and
我有以下代码。 from xml.dom.minidom import Document doc = Document() root = doc.createElement('root') doc.a
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Find text string in jQuery and make it bold 如何使用 jQuer
我使用 libmagic 在我的元素的 Web 界面中获取文件的 MIME 类型。我在 css 和 js 文件上得到文本/纯 mime 类型。 例如 chromium 显示以下警告: Resource
起初我必须阅读很多教程,但我仍然不知道我做错了什么...... 我想内联使用 4 个 div。在我想放置的那些 div 中:文本、图像、文本、文本。我希望中间文本自动设置为最大宽度。 我写了一个简单的
我想替换所有出现的 [b: "text"]至text使用 JavaScript 和 RegEx。目前我知道如何替换 [b: ""]至使用'/\[b: ""\]/g'但我不知道如果 " 之间有文本该怎么
这可能是一个幼稚的问题,但我想知道是否有比使用 text() 更好的方法将文本添加到绘图中。注意,我也在使用 layout()以及。具体来说,我有一个情节的一部分,我想在其中添加一些带有标题的文本,然
我必须反复从 latex 源粘贴代码,因此每次都必须做很多查找和替换操作('“a'=>'ä','” o'=>'ö',...) 。 有没有一种方法可以存储这些搜索和替换规则,例如,我可以通过一次按键执行
当我在Sublime Text 3代码屏幕中编写代码时,它连续地向右滑动,如图所示。我该怎么办? 请注意第10行。 最佳答案 如果您只想为当前 View (正在编辑的当前文件)激活自动换行,只需vie
是否有可能更改 sublime text 中的默认字体目录?我只想使用可移植 sublime 文本存储在我的 pendrive 上的字体,这样我就不必在我使用可移植 sublime 文本的每台机器上安
我是 Android 开发的新手,我有一个愚蠢的问题。如何将“文本字段”框放在一行中的文本旁边。 例子: Please Enter the number: [ ] 关于 "t
我想自动将“我的文本”更改为“我的文本”,因为这是用德语写的正确方式。引号可以在文本中的任何位置。 有没有一种简单的方法可以实现这一点? 解决方案应该检查第一个字符,最后一个字符,比如“this”,或
我想知道是否有特殊的语法来绑定(bind)与现有文本连接的文本。 像这样。 显然,这行不通。 什么是最佳实践? 使用 SL4。 最佳答案 使用StringFormat在 Binding 上。 WPF
我认为它应该打印“真实文本”,因为它相当于 true console.log('true text' || true ? 'text' : 'text1'); 但是,输出是“文本”;抱歉,如果是愚蠢的
有没有办法通过 css 打破文本,以便中间有一个“空白”?目前我正在通过手工打破文本来解决这个问题 -但这是愚蠢的。我知道有一个函数可以让文本在另一个 div 中结束和开始,但 IE 不支持它。 文本
我想为我的Tcl/Tk工具实现一个效果:在text控件中,根据具体情况,希望高亮一些线条的背景色,其他线条正常透明.有可能吗? 我尝试了一些选项,例如:-highlightbackground 、-i
我正在尝试解析原始维基百科文章内容,例如the article on Sweden ,使用re.sub()。但是,我在尝试替换 {{some text}} block 时遇到了问题,因为它们可以包含更
我试图先删除 ComboBox 中的所有内容。然后在其前面添加文本,但保留了一些旧文本。有没有办法重置或清除 ComboBox?或者我怎样才能最好地实现这一目标? public void GetBad
我知道我们应该创建 Example对象并将其传递给 nlp.update() 方法。根据 docs 中的示例, 我们有 for raw_text, entity_offsets in train_da
我是一名优秀的程序员,十分优秀!