【问题标题】:How to initialise @State variables depending on each other in Swiftui?如何在 Swiftui 中根据彼此初始化 @State 变量?
【发布时间】:2020-07-14 21:55:51
【问题描述】:

我需要将我的 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。感谢您的帮助)

【问题讨论】:

  • 您是否介意发帖MultilineTextField 以获得进一步的帮助

标签: swift swiftui


【解决方案1】:

应该不一样,因为view是struct,所以你在按钮动作中调用updateTextStyle()是没有效果的,因为应用于上面textFieldcopy

取而代之的方法应该是如下(scratchy)

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")
            }
        }
    }
}

【讨论】:

  • 我添加了附加信息以阐明所需的行为。我的问题是我试图从 MultilineTextField Coordinator 访问选定的文本并将其传递给 struct 方法以更改视图中的属性文本,因此我不能从 ContentView 设置
猜你喜欢
  • 2020-03-04
  • 2021-10-28
  • 1970-01-01
  • 2019-11-03
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多