如何在Swiftui中初始化彼此依赖的@State变量?

时间:2020-07-14 21:55:51

标签: swift swiftui

我需要将我的MultilineTextField视图(包装的UITextView)分配给变量textField,以便稍后能够从ContentView中的按钮调用其方法updateTextStyle(将选定的文本转换为粗体)。问题在于MultilineTextField依赖于@State var range,因此无法编译。有什么可能的解决方法?

struct ContentView: View {
@State private var range: NSRange?
@State var textField = MultilineTextField(rangeSelected: $range)

var body: some View {
    VStack {
        textField
        Button(action: {
            self.textField.updateTextStyle()
        }) {
            Text("Update text style")
        }
    }
}

}

在相关的情况下,MultilineTextField(我试图删除不必要的-希望很清楚)

struct MultilineTextField: UIViewRepresentable {
    let textView = UITextView()

    @Binding var rangeSelected: NSRange?
    @State var attributedNoteText = NSMutableAttributedString(string: "Lorem ipsum")

    func makeUIView(context: Context) -> UITextView {
        // ...
    
        textView.delegate = context.coordinator
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = attributedNoteText
    }
    
    func updateTextStyle() {
        if self.rangeSelected != nil {
            // apply attributes (makes the selected text bold)
        } else {
            print("rangeSelected is nil")
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self, $attributedNoteText)
    }
    
    class Coordinator: NSObject, UITextViewDelegate {
        var parent: MultilineTextField
        var text: Binding<NSMutableAttributedString>
        
        init(parent: MultilineTextField, _ text: Binding<NSMutableAttributedString>) {
            self.parent = parent
            self.text = text
        }
        
        func textViewDidChange(_ textView: UITextView) {
            let attributedStringCopy = textView.attributedText?.mutableCopy() as! NSMutableAttributedString
            parent.textView.attributedText = attributedStringCopy
            self.text.wrappedValue = attributedStringCopy
        }
        
        func textViewDidChangeSelection(_ textView: UITextView) {
            parent.rangeSelected = textView.selectedRange // not sure about this one
        }   
    }
}

(我知道这里可能还会有一些其他错误-这是我第一次在SwiftUI中使用UIKit。感谢您的帮助)

1 个答案:

答案 0 :(得分:0)

应该有所不同,因为视图是结构,所以按钮操作中的调用updateTextStyle()无效,因为应用于textField copy >

相反,方法应类似于(抓抓)

struct ContentView: View {
    @State private var range: NSRange?

    // example of style, on place of color your style
    @State var color: Color = .black
    
    var body: some View {
        VStack {
            MultilineTextField(rangeSelected: $range)
                .foregroundColor(self.color)          // style state dependency
            Button(action: {
                self.color = .red     // specify new style
            }) {
                Text("Update text style")
            }
        }
    }
}