对于一个SwiftUI手表应用,如何在一个ContentView中显示我的模型数组的内容,每个数组元素的内容都在自己的子视图中?

问题描述 投票:0回答:1

我在做一个Apple Watch应用,使用SwiftUI。我的想法是在一个手表ContentView中使用ContentView Body View中的四个独立的 "子视图 "来显示不同的活动内容。我不想使用List来显示活动内容,而是想在ContentView中使用多个自定义视图。

我希望每个单独的 "子视图 "都能显示我的模型中的独特内容。

我的模型叫做QuadActivity,有以下内容。

struct QuadActivity: Identifiable {

  let id = UUID()
  var activityImage: Image
  var activityTitle: String
}

我目前已经创建了一个QuadActivity的扩展,如下所示,以保存一些硬编码的测试数据。

extension QuadActivity {

  static func all() -> [QuadActivity] {

     return [
        QuadActivity(activityImage: activityImage1, activityTitle: "activity1"),
        QuadActivity(activityImage: activityImage2, activityTitle: "activity2"),
        QuadActivity(activityImage: activityImage3, activityTitle: "activity3"),
        QuadActivity(activityImage: activityImage4, activityTitle: "activity4")]
  }
}

我的ContentView.swift主体视图是由一个VStack和2个HStack组成的。每个 HStack 包含 2 个我的 "子视图",并带有杂项间隔和填充修改器。每一个 "子视图 "都应该显示来自实例属性的一个数组元素的内容。

 var activityArrayEntry = QuadActivity.all()

因此 HStack 1 应该显示 activityImage1 和 activity1 以及 activityImage2 和 activity2。另一个 HStack 应该显示项目 3 和 4 的数组元素。

我不知道如何访问activityArrayEntry数组元素,并在其中一个 "子视图 "中显示每个元素。

我想我可以使用一个。

ForEach(activityArrayEntry) { activity in
  VStack and embedded HStack code here}

然后通过上面的ForEach循环显示 "子视图 "内容。但是,由于我所有的VStack和HStack以及 "subview "代码都在ForEach循环内,所以所有的 "subview "都会显示相同的数组元素活动内容,因为循环包含了所有的视图信息,只需通过一次循环即可。我希望每个 "子视图 "都显示一个唯一的数组元素的内容。

如果我把ForEach移到ZStack和HStack代码内,用于每个HStack "subview "的显示部分,它将循环通过数组条目,但循环不会包含所有的 "subviews "代码,我不会让所有的 "subviews "只显示1个数组元素的活动数组内容。

也许使用ForEach()循环不是办法。有没有其他方法可以从我的实例变量中访问各个数组元素,从而使每个独特的数组元素只在1个 "子视图 "中使用?

同样,我如何让整体的ContentView.swift在ZStack和HStack结构中显示4个 "子视图",使每个 "子视图 "只显示1个数组元素的活动内容。

61520 - 下面添加ContentView。

这是我目前的ContentView。请注意一些注释行,我最终会重新回到这里,以便从我的模型的@Published Observable Object中使用观察对象模型方法。这最终将是(也许)方法,而不是我的模型中的函数all(),我现在使用硬编码数据来测试我的应用程序中的数据流......因此,最初的问题问题。注意--对QuadView()的调用只是对一个提取的子视图的调用,在这里我定义了子视图的显示(简单的图像和文本)。

import SwiftUI

struct ContentView: View {

//    @ObservedObject var quadViewVM = QuadViewVM()
    var activityArrayEntry = QuadActivity.all()

    var body: some View {

        ZStack {

            HStack {

                Divider()
                    .frame(height: 175.0)

            }
            .edgesIgnoringSafeArea(.horizontal)

            ForEach(activityArrayEntry) { activity in

            VStack {


                HStack(alignment: .center) {
                    QuadView(activityTitle: "\(activity.activityTitle)", activityImage: activity.activityImage)

                        //                        NavigationLink(destination: QuadDetail(content: , newActivity: false)) {
                        //
                        //                        }
                        .frame(width: 85.0, height: 100.0)
                        .buttonStyle(PlainButtonStyle())

                    Spacer()

                    QuadView(activityTitle: "\(activity.activityTitle)", activityImage: activity.activityImage)

                        //                        NavigationLink(destination: QuadDetail()) {
                        //
                        //                        }

                        .frame(width: 85.0, height: 100.0)
                        .buttonStyle(PlainButtonStyle())
                }
                .padding(.horizontal, 15.0)
                .padding(.bottom, -10.0)

                Divider()

                HStack(alignment: .center) {
                    QuadView(activityTitle: "\(activity.activityTitle)", activityImage: activity.activityImage)

                        //                        NavigationLink(destination: QuadDetail()) {
                        //
                        //                        }

                        .frame(width: 85.0, height: 100.0)
                        .buttonStyle(PlainButtonStyle())

                    Spacer()

                    QuadView(activityTitle: "\(activity.activityTitle)", activityImage: activity.activityImage)

                        //                        NavigationLink(destination: QuadDetail()) {
                        //
                        //                        }
                        .frame(width: 85.0, height: 100.0)
                        .buttonStyle(PlainButtonStyle())
                }

                .padding([.leading, .bottom, .trailing], 15.0)
                .padding(.top, -10.0)


                .padding(.top, 30.0)
                .edgesIgnoringSafeArea(.horizontal)

            }
        }
    }
}
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
arrays swiftui watch
1个回答
0
投票

而不是静态的 QuadActivity.all() 您可以将您的数据存储在 ViewModel:

class QuadViewVM: ObservableObject {
    @Published var quadActivities: [QuadActivity] = [
        QuadActivity(activityImage: activityImage1, activityTitle: "activity1"),
        QuadActivity(activityImage: activityImage2, activityTitle: "activity2"),
        QuadActivity(activityImage: activityImage3, activityTitle: "activity3"),
        QuadActivity(activityImage: activityImage4, activityTitle: "activity4"),
    ]
}

在你的 ContentView 您可以通过使用两个 ForEach 循环(因为它是一个二维网格)。

struct ContentView: View {
    @ObservedObject var quadViewVM = QuadViewVM()
    let columnCount = 2
    var rowCount: Int {
        quadViewVM.quadActivities.count / columnCount
    }

    var body: some View {
        ZStack {
            // Horizontal divider
            VStack {
                Divider()
            }
            .edgesIgnoringSafeArea(.horizontal)
            // Vertical divider
            HStack {
                Divider()
            }
            .edgesIgnoringSafeArea(.vertical)

            activityGrid
        }
    }

    var activityGrid: some View {
        VStack {
            ForEach(0 ..< self.rowCount) { row in
                HStack {
                    ForEach(0 ..< self.columnCount) { column in
                        self.quadView(row: row, column: column)
                    }
                }
            }
        }
    }

    func quadView(row: Int, column: Int) -> some View {
        let activity = quadViewVM.quadActivities[row * columnCount + column]
        return QuadView(activity: activity)
            .frame(width: 85.0, height: 100.0)
            .buttonStyle(PlainButtonStyle())
    }
}

这个... QuadView 被提取到另一个函数中,以使其更易读,更容易应用视图修改器。

我还建议将整个 QuadActivity 变量为 QuadView (而不是它的单个组件)--特别是在你需要它们的时候。

struct QuadView: View {
    let activity: QuadActivity

    var body: some View {
        ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.