我在做一个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()
}
}
而不是静态的 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 {
...
}
}