ios VStack inside ForEach inside Array[查看]

w1jd8yoj  于 12个月前  发布在  iOS
关注(0)|答案(1)|浏览(95)

获取数组大小= 1,但我在其中添加了4个对象。
在SwiftUI中,我将VStack放在包含视图的Array中的ForEach循环中。它使用上述数据创建只有一个步骤,其中有4个对象。
我基本上是从API解析数据的模型对象,并使用该模型创建动态视图。
FYI -我第一次使用SwiftUI,并将该模型从我的UIKit ViewController传递到SwiftUI View文件。
Param通过并工作正常。
此外,我正在创建StepperView用于跟踪包裹交付。
为了更好的想法,把我的UIClass代码贴在这里。(我只粘贴了理解所需的主要核心代码,所以不用担心StepperView的其他实现)

struct TrackingStepperView: View {
    var trackingData : [TrackingModel]?
    init(param: [TrackingModel]?) {
        self.trackingData = param
    }
    
    var body: some View {
        let steps = [
            ForEach(trackingData!) { item in
                VStack(alignment: .leading) {
                    Text(item.getTitle()!).eraseToAnyView()
                    Text(item.getDescription()!).eraseToAnyView()
                    Text(item.getDateTime()!).eraseToAnyView()
                }
                .background(Color(UIColor.clear))
            }
        ]
        
        let _ = print("steps.count = ", steps.count)
        
        StepperView()
            .addSteps(steps)
    }
}

同样,如果我尝试像在swift UIKit中那样使用数组。获取以下错误

  • StepperView()类型“any View”不能符合“View”
  • 类型可以符合协议
  • 类型“()”不能符合“View”
  • 类型“()”不能符合“可扩展性RotorContent”
  • 类型“any View”不能符合“View”

感谢您抽出时间来阅读它。

xhv8bpkk

xhv8bpkk1#

我会把你的代码修改成一个带注解的工作版本,看看它是否有用:
1.在Swift中,你通常不需要像你提供的那样使用init:你的trackingData已经是内部的了,所以你应该能够运行一个合成的init,而不需要创建你的自定义init。
1.您的TrackingData应该符合Identifiable协议。(可选)我还将更改TrackingModel,以便访问属性,而不是像getTitle()这样的getter:

struct TrackingModel: Identifiable {
    let title: String?
    let description: String?
    let dateTime: Date?

    // Identifiable: as example, sing title, but use whatever is unique
    var id: String {
        title ?? UUID().uuidString
    }
}

1.将输入数据表示为@State@Environment(取决于您的需要)。举例来说:

@State var trackingData: [TrackingModel]

1.在body中,首先你需要在顶层有某种容器。根据你的数据,我建议从List开始。它有一些问题,但总的来说,它是显示数据数组的最传统的方法:

var body: some View {
     List {
         // Your items here
     }
 }

1.同时避免用力打开 Package 。而是提供默认值。
1.迭代 data 并显示(不存储)视图:
这是你观点的最终版本:

struct TrackingModel: Identifiable {
    
    var id: String {
        title ?? UUID().uuidString
    }
    
    let title: String?
    let description: String?
    let dateTime: Date?
}

struct TrackingStepperView: View {
    
    @State var trackingData: [TrackingModel]
    
    var body: some View {
        List {
            ForEach(trackingData) { item in
                VStack(alignment: .leading) {
                    Text(item.title ?? "Unknown")
                    Text(item.description ?? "")
                    Text(item.dateTime?.ISO8601Format() ?? "--")
                }
            }
        }
    }
}

它可以通过提供跟踪数据来示例化:

TrackingStepperView(trackingData: [
            TrackingModel(title: "one", description: "one one", dateTime: .now),
            TrackingModel(title: "two", description: "two two", dateTime: .now)
        ])

是的,您可以将跟踪数据设置为可选,但我认为理想情况下,您不需要:如果没有跟踪数据,则根本没有显示此视图指针。相反,父视图/调用者可以这样做:

if let trackingData = trackingData {
    TrackingStepperView(trackingData: trackingData)
} else {
    EmptyView() // or some other view for empty state
}

相关问题