gpt4 book ai didi

swiftui - 在 SwiftUI 文本中获取单词的框架

转载 作者:行者123 更新时间:2023-12-01 21:40:38 34 4
gpt4 key购买 nike

我想找到一个词在句子中的位置,以便为该词设置框架。像这样例如: enter image description here

目前是否可以在 SwiftUI 中执行此操作

我写了一些代码,这就是我得到的

import SwiftUI

struct ContentView: View {

@State var text = "I usually get ----- around nine o'clock every morning"
@State var rects = [CGRect.zero]

var body: some View {
ZStack {
TextView(text: $text, rects: $rects)
.overlay(
ForEach(0..<self.rects.count, id: \.self) { index in
RoundedRectangle(cornerRadius: 6)
.frame(width: self.rects[index].size.width, height: self.rects[index].size.height)
.position(self.rects[index].origin)
.foregroundColor(Color.red)
}
)

}
}
}

struct TextView: UIViewRepresentable {

@Binding var text: String
@Binding var rects: [CGRect]

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeUIView(context: Context) -> UITextView {

let textView = UITextView()
textView.delegate = context.coordinator
textView.isEditable = true
textView.isUserInteractionEnabled = true
textView.font = UIFont.systemFont(ofSize: 24)
DispatchQueue.main.async {
let ranges = self.searchRanges(in: textView.text)
self.rects = self.viewRects(for: ranges, textView: textView)
}
return textView
}

func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
}

class Coordinator : NSObject, UITextViewDelegate {

var parent: TextView

init(_ uiTextView: TextView) {
self.parent = uiTextView
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return true
}

func textViewDidChange(_ textView: UITextView) {
self.parent.text = textView.text
}
}

func searchRanges(in text: String) -> [Range<String.Index>] {
var ranges = [Range<String.Index>]()
var searchRange = text.startIndex ..< text.endIndex
var range = text.range(
of: "-----",
options: .caseInsensitive,
range: searchRange,
locale: nil
)
while let findedRange = range {
ranges.append(findedRange)
searchRange = findedRange.upperBound ..< text.endIndex
range = text.range(
of: "-----",
options: .caseInsensitive,
range: searchRange,
locale: nil
)
}

return ranges
}

func viewRects(for rnges: [Range<String.Index>], textView: UITextView) -> [CGRect] {
var rects = [CGRect]()
for range in rnges {
let upperBound = range.upperBound.utf16Offset(in: textView.text)
let lowerBound = range.lowerBound.utf16Offset(in: textView.text)
let length = upperBound - lowerBound

if let start = textView.position(from: textView.beginningOfDocument, offset: lowerBound),
let end = textView.position(from: start, offset: length),
let txtRange = textView.textRange(from: start, to: end) {
var rect = textView.firstRect(for: txtRange)
rect.origin.x = rect.origin.x
rect.origin.y = rect.midY
rects.append(rect)
}
}
return rects
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

enter image description here

UIKit 上的代码与 Storyboard相同

enter image description here

最佳答案

您可以通过拆分文本、遍历文本,然后使用overlay 来框住您想要的单词来实现这一点。

看这个例子:

struct HighlightView: View {
var words: [FramableWord] = []

struct FramableWord: Identifiable {
let id = UUID()
let text: String
let isFramed: Bool
}

func frame(word: String, in text: String) -> [FramableWord] {
return text.split(separator: " ").map(String.init).map {
FramableWord(text: $0, isFramed: $0 == word)
}
}

init() {
words = frame(word: "up", in: "I get up at 9")
}

var body: some View {
HStack(spacing: 2) {
ForEach(words) { word -> AnyView in
if word.isFramed {
return AnyView(
Text(word.text)
.padding(2)
.overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.blue, lineWidth: 2))
)
}

return AnyView(Text(word.text))
}
}
}
}

结果:

example

关于swiftui - 在 SwiftUI 文本中获取单词的框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61483735/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com