首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI UIViewRepresentable UITextView绑定

SwiftUI UIViewRepresentable UITextView绑定
EN

Stack Overflow用户
提问于 2020-01-21 11:45:52
回答 2查看 5.9K关注 0票数 6

多行文本输入目前在SwiftUI中本机不受支持(希望不久就能添加此功能!)因此,我一直试图使用组合框架来实现来自UITextView的UIKit,它确实支持多行输入,但结果却参差不齐。

这是我为创建文本视图而创建的代码:

代码语言:javascript
复制
struct MultilineTextView: UIViewRepresentable {

    @Binding var text: String


    func makeUIView(context: Context) -> UITextView {
        let view = UITextView()
        view.isScrollEnabled = true
        view.isEditable = true
        view.isUserInteractionEnabled = true
        view.backgroundColor = UIColor.white
        view.textColor = UIColor.black
        view.font = UIFont.systemFont(ofSize: 17)
        view.delegate = context.coordinator
        return view
    }

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

    func frame(numLines: CGFloat) -> some View {
        let height = UIFont.systemFont(ofSize: 17).lineHeight * numLines
        return self.frame(height: height)
    }

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

    class Coordinator: NSObject, UITextViewDelegate {
        var parent: MultilineTextView

        init(_ parent: MultilineTextView) {
            self.parent = parent
        }

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

然后,我在swiftUI视图中实现了它,如下所示:

代码语言:javascript
复制
MultilineTextView(text: title ? $currentItem.titleEnglish : $currentItem.pairArray[currentPair].english)//.frame(numLines: 4)

并将其绑定到状态变量:

代码语言:javascript
复制
@State var currentItem:Item

挺管用的。但是,状态var currentItem:Item包含一个字符串数组,然后我将使用按钮循环这些字符串,这些按钮根据输入到MultilineTextView的内容更新字符串数组。在这里,我遇到了一个问题: MultilineTextView似乎只绑定到数组中的第一个字符串项,然后它就不会改变了。当我使用迅捷use的本机TextField视图时,这个功能工作得很好,我可以循环字符串数组并通过将文本输入到TextField来更新它。

我想我一定是在MultilineTextView结构中遗漏了允许这个功能的东西。任何指针都会被感激地接收。

更新:添加的模型结构

代码语言:javascript
复制
struct Item: Identifiable, Codable {
    let id = UUID()
    var completed = false
    var pairArray:[TextPair]
}

struct TextPair: Identifiable, Codable {
    let id = UUID()
    var textOne:String
    var textTwo:String
}

编辑:,所以我做了更多的调查,我发现了我认为问题所在。当触发textViewDidChange的UITextView时,它确实发送更新的文本,我可以在控制台中看到。奇怪的是,updateUIView函数也会被触发,它用绑定变量中的内容更新UITextView的文本,然后通过textViewDidChange发送更新。其结果是,当您键入UITextview时,它只会拒绝更改。奇怪的是,它适用于数组中的第一个字符串,但是当项被更改时,它将不再工作。

EN

回答 2

Stack Overflow用户

发布于 2020-01-22 13:48:56

SwiftUI似乎为每个绑定创建了两个UIViewRepresentable变体,但在状态切换时不切换它们,即title被切换.可能是因为缺陷,值得提交给苹果。

我已经找到了可行的解决办法(用Xcode 11.2 / iOS 13.2进行了测试),可以显式地使用以下不同的视图

代码语言:javascript
复制
if title {
    MultilineTextView(text: $currentItem.titleEnglish)
} else {
    MultilineTextView(text: $currentItem.pairArray[currentPair].textOne)
}
票数 2
EN

Stack Overflow用户

发布于 2020-01-30 13:25:45

最后,我发现了这个问题,它之所以没有更新,是因为我传入了一个带有两个状态变量的字符串。您可以看到,在下面的行中,currentItem是一个状态变量,但currentPair是另一个状态变量,它提供了一个索引号来定位字符串。后者没有被更新,因为它也没有通过绑定传递到多行文本视图中。

代码语言:javascript
复制
MultilineTextView(text: title ? $currentItem.titleEnglish : $currentItem.pairArray[currentPair].english)

我最初以为传入一个会很好,而父视图将处理另一个视图,但事实证明并非如此。我通过创建两个绑定变量来解决我的问题,这样我就可以以动态的方式找到我想要的字符串。现在听起来很蠢,但当时我看不见。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59840437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档