SwiftUI 值未更新

问题描述 投票:0回答:1

我有一个 SwiftUI 文本编辑器,每当我按下更新按钮时,颜色应该应用于文本,但它只是重置为初始值。有人可以帮助我吗?

import SwiftUI

class TextColorUpdater: ObservableObject {

    @Published var attributedText: NSAttributedString

    init(initialText: String) {
        self.attributedText = TextColorUpdater.highlightText(initialText)
    }
    
    func update() {
        print(attributedText.string)
        self.attributedText = TextColorUpdater.highlightText(attributedText.string)
    }
    
    static func highlightText(_ text: String) -> NSAttributedString {
        let mutableAttributedString = NSMutableAttributedString(string: text)
        
        if let regex = try? NSRegularExpression(pattern: "\\bred\\b", options: .caseInsensitive) {
            let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
            for match in matches {
                let nsRange = match.range
                mutableAttributedString.addAttribute(.foregroundColor, value: UIColor.red, range: nsRange)
            }
        }
        
        return mutableAttributedString
    }

}

struct HighlightedTextEditor: UIViewRepresentable {
    
    @Binding var attributedText: NSAttributedString

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.isEditable = true
        textView.isSelectable = true
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = attributedText
    }

}

struct ContentView: View {

    @StateObject var textColorUpdater = TextColorUpdater(initialText: "This is a redd red red red car. The sky is not red")

    var body: some View {
        VStack {
            HighlightedTextEditor(attributedText: $textColorUpdater.attributedText)
            
            Button("Update") {
                textColorUpdater.update()
            }
        }
    }

}



swift swiftui syntax syntax-highlighting nsattributedstring
1个回答
0
投票

UITextView
的文本发生变化时,你永远不会更新
@Binding
!绑定不会知道它与
UITextView
的文本相关并自行更新!

您需要检测

UITextView
的文本变化。您可以使用
UITextViewDelegate
来做到这一点。为了符合这一点,您需要一个
Coordinator

struct HighlightedTextEditor: UIViewRepresentable {
    
    @Binding var attributedText: NSAttributedString

    @MainActor
    class Coordinator: NSObject, UITextViewDelegate {
        let textView = UITextView()
        
        var textDidChange: ((NSAttributedString) -> Void)?
        
        override init() {
            textView.isEditable = true
            textView.isSelectable = true
            super.init()
            textView.delegate = self
        }
        
        func textViewDidChange(_ textView: UITextView) {
            textDidChange?(textView.attributedText)
        }
    }
    
    func makeUIView(context: Context) -> UITextView {
        context.coordinator.textView
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = attributedText
        context.coordinator.textDidChange = { attributedText = $0 }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.