简体   繁体   English

如何使用 collect 在 SwiftUI 中创建视图

[英]How to create views in SwiftUI using collect

I am trying to figure out a way to insert multiple arrays of views in a VStack in SwiftUI using collect() operator.我试图找出一种使用collect()运算符在 SwiftUI 中的 VStack 中插入多个视图数组的方法。

struct ChatsTab: View {
    var subscriptions = Set<AnyCancellable>()
    var body: some View {
        VStack {
            ["A", "B", "C", "D", "E"].publisher.collect(2).sink(receiveCompletion: { _ in
                // Do nothing on completion
            }) { (stringArray) in
                HStack {
                    Text(stringArray[0])
                    Text(stringArray[1])
                }
            }
        .store(in: &subscriptions)
        }
    }
}

But I'm getting this below error:但我收到以下错误:

Cannot convert value of type '()' to closure result type '_'

I want to do this with collect only so I can add my text views in pair.我只想使用collect来做到这一点,这样我就可以成对添加我的文本视图。 I know I have other options but I want to get it done with collect only.我知道我还有其他选择,但我只想通过collect来完成它。

You just have to rearrange things.你只需要重新安排事情。 The real issue is not the collect , the issue is that you're trying to execute arbitrary code inside the VStack .真正的问题不是collect ,问题是您试图在VStack内执行任意代码。 The VStack is a function builder and between it's curly braces goes a list of views and possibly some basic if logic only. VStack是一个函数构建器,在它的大括号之间是一个视图列表,可能还有一些基本的if逻辑。 Not arbitrary code, like the kind you include in a regular function.不是任意代码,就像您包含在常规函数中的那种。 So if you take the publisher code out of the VStack it will compile.因此,如果您从 VStack 中取出发布者代码,它将编译。 Where you put it is up to you, you can have it in init() , called from another function, or int didAppear view modifier (just not inside the VStack directly).你把它放在哪里取决于你,你可以把它放在init() ,从另一个函数调用,或者 int didAppear视图修饰符(只是不直接在 VStack 内)。

A second issue is that the collect will publish another array (one of length 2).第二个问题是 collect 将发布另一个数组(长度为 2 的数组)。 You will essentially end up with an array of String arrays (or you can just consume them as they are published and not keep them around, depending on what you are trying to do).你最终会得到一个 String 数组的数组(或者你可以在它们发布时使用它们而不是保留它们,这取决于你想要做什么)。 You can also use the simpler version of sink since the Error of the publisher here is Never .您也可以使用更简单的sink版本,因为这里发布者的ErrorNever Anyway here is something incorporating the above changes:无论如何,这里有一些包含上述更改的内容:


import SwiftUI
import Combine

var subscriptions = Set<AnyCancellable>()

struct ContentView: View {

  @State var stringArrays: [[String]] = []

    var body: some View {
      ForEach(stringArrays, id: \.self) { stringArray in
        HStack {
          Text(stringArray.count > 0 ? stringArray[0] : "")
          Text(stringArray.count > 1 ? stringArray[1] : "")
        }
      }.onAppear() {
        ["A", "B", "C", "D", "E"].publisher
          .collect(2)
          .sink(receiveValue: { (stringArray) in
            self.stringArrays.append(stringArray)
          }).store(in: &subscriptions)
      }
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM