提问人:Yousif Ismat 提问时间:9/15/2023 最后编辑:Yousif Ismat 更新时间:9/15/2023 访问量:52
制作指针,在字符串上读取字符串 - SwiftUI
Making Pointer that reads string while over it - SwiftUI
问:
我想在 SwiftUI 中实现以下行为,但我不知道如何操作:
想象一下,有一个包含字符串(或属性字符串)的文本,你还有一个指针,可以像鼠标图标(或任何图标)一样悬停在字符串的字母上,当指针放在一个字母上时,该字母会突出显示(即颜色不同)。
我不想要的: 我不希望您使用不同的文本并使用 HStack 和 Foreach 将它们相加,我希望它们在一起,因为我希望它适用于所有语言,并且提到的方法仅适用于仅具有不连接字母的语言。
可能吗?
答:
0赞
KerryDong
9/15/2023
#1
是的,使用 NSAttributedString,NSTextAttachment 可以满足您的需求。
我把它封装在:HighlightWithCursorLabel
struct HighlightWithCursorLabel: UIViewRepresentable {
var originText: String
var color: UIColor
@Binding var highlightIndex: Int
var configuration = { (view: UILabel) in }
init(originText: String, color: UIColor, highlightIndex: Binding<Int>, configuration: @escaping (UILabel) -> () = { _ in }) {
self.originText = originText
self.color = color
self._highlightIndex = highlightIndex
self.configuration = configuration
}
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.text = originText
label.textColor = UIColor(Colors.subText)
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
configuration(uiView)
if highlightIndex > originText.count { return }
let attributString = NSMutableAttributedString(string: originText)
let nsRange = NSRange(location: 0, length: highlightIndex)
let attribute = [NSAttributedString.Key.foregroundColor: color]
attributString.addAttributes(attribute, range: nsRange)
let attachment = NSTextAttachment(image: UIImage(systemName: "cursorarrow")!.withTintColor(color)) // replace it to any UIImage
let attachmentString = NSAttributedString(attachment: attachment)
attributString.insert(attachmentString, at: highlightIndex)
uiView.attributedText = attributString
}
}
用法
struct HighlightSampleView: View {
@State private var highlightIndex: Int = 0
private var text = "Hello World~~~~~"
var body: some View {
HighlightWithCursorLabel(originText: text, color: UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1.0), highlightIndex: $highlightIndex)
.onAppear {
highlightText()
}
}
// To show the highlight effect, replace it when you want to update index
private func highlightText() {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
highlightIndex += 1
if highlightIndex > text.count {
timer.invalidate()
}
}
}
}
struct HighlightSampleView_Previews: PreviewProvider {
static var previews: some View {
HighlightSampleView()
}
}
结果
评论
0赞
Yousif Ismat
9/16/2023
感谢您的帮助,但问题是光标不是作为单独的实体在文本上,而是嵌入在属性字符串中,这会产生我不想要的将文本向左推的效果。你能让它悬停在上面而不干扰文本,除了突出显示吗?
0赞
KerryDong
9/16/2023
如果您只想允许用户将鼠标悬停在文本上并突出显示它,您可以考虑使用具有选择/突出显示文本功能的本机。然后,您可以添加一个并根据用户的点击和拖动不断更新其位置。如果要进一步自定义文本的突出显示颜色,可以尝试使用 、convert(_:from:) 和 glyphIndex(for:in:)。UITextView
UIImageView
NSAttributedString
评论