问题
I want to highlight texts in UITextView. Here is the CustomTextView I made.
struct CustomTextView: UIViewRepresentable {
@ObservedObject var tmpTextVM: TmpTextViewModel
func makeUIView(context: UIViewRepresentableContext<CustomTextView>) -> UITextView {
let textView = UITextView()
textView.backgroundColor = UIColor.clear
textView.isScrollEnabled = false
textView.text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
textView.font = UIFont(name: "ArialMT", size: 20)
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.textColor = tmpTextVM.color
let range = (uiView.text as NSString).range(of: uiView.text)
var rect = uiView.layoutManager.boundingRect(forGlyphRange: range, in: uiView.textContainer)
rect.size.width += 25
rect.size.height += 10
rect.origin.x += uiView.textContainerInset.left - 10
rect.origin.y += uiView.textContainerInset.top - 5
uiView.viewWithTag(300)?.removeFromSuperview()
let view = UIView()
view.backgroundColor = UIColor.blue
view.layer.cornerRadius = 10
view.frame = rect
view.tag = 300
uiView.addSubview(view)
uiView.sendSubviewToBack(view)
}
}
And using this like below.
struct TmpView7View: View {
@ObservedObject var tmpTextVM: TmpTextViewModel
var body: some View {
VStack {
Button(action: {
tmpTextVM.changeColor(UIColor.red)
}){
Image(systemName:"eyedropper.full")
}
CustomTextView(tmpTextVM: tmpTextVM)
.frame(width:300, height: 300, alignment: .topLeading)
.border(Color.red, width: 1)
}
}
}
But it highlights only first line of UITextView. And if it was updated by tapping the button, it highlights all text. It seems like if updeteUIView is called again, texts are highlighted properly. I want it to be highlighted at the first time when the textView was rendered. Is it possible to do that??
来源:https://stackoverflow.com/questions/65168981/swiftui-boundingrect-doesnt-work-fine-by-uiviewrepresentable-updateuiview