如何从嵌套的 ForEach 循环中获取连续的索引号?
How to get continuous index numbers from nested ForEach loop?
我正在为我的小部件扩展使用 4 块网格。
我想用一组元素填充这些网格。
let exampleArray = ["test1","test2","test3","test4"]
当我使用两个嵌套的 ForEach 循环时,我无法获取第 4 个索引中的元素。
VStack {
ForEach((0..<2)) { column in
HStack {
ForEach((0..<2)) { index in
ZStack (alignment: .bottomLeading) {
Text(newsList[(index+column)]) // 0+0, 1+0, 0+1, 1+1
// Text = test1, test2, test2, test3
}
}
}
}
}
有什么办法可以解决这个问题吗?因为它在View
,我无法使用任何操作
视图的完整代码:
struct AppWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily)
var widgetFamily
var body: some View {
VStack(alignment: .trailing, spacing: 6) {
Image("logo")
.frame(maxWidth: .infinity, alignment: .leading)
if widgetFamily == .systemLarge {
VStack {
ForEach((0..<2)) { column in
HStack {
ForEach((0..<2)) { index in
ZStack (alignment: .bottomLeading) {
if let url = URL(string: imageList[(index+column)]), let imageData = try? Data(contentsOf: url),
let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
} else {
Image("ph_background")
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
}
Text(newsList[(index+column)])
.font(.system(size: 12))
.foregroundColor(.white)
.fontWeight(.light)
// .frame(maxHeight: 50)
.background(Rectangle().fill(Color.black).blur(radius: 20))
.padding(.bottom, 5)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.top, 5)
}
}
}
}
}
}
}
}
解决方案
请检查已接受的答案。
struct AppWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily)
var widgetFamily
var body: some View {
var columns: [GridItem] =
Array(repeating: .init(.fixed(100)), count: 2)
if widgetFamily == .systemLarge {
LazyVGrid(columns: columns) {
ForEach((0..<4)) { index in
ZStack (alignment: .bottomLeading) {
if let url = URL(string: imageList[(index)]), let imageData = try? Data(contentsOf: url),
let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
} else {
Image("ph_background")
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
}
Text(newsList[(index)])
.font(.system(size: 12))
.foregroundColor(.white)
.fontWeight(.light)
// .frame(maxHeight: 50)
.background(Rectangle().fill(Color.black).blur(radius: 20))
.padding(.bottom, 5)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.top, 5)
}
}
}
}
}
}
使用LazyVGrid
我觉得你真的应该为此使用 LazyVGrid
...
https://developer.apple.com/documentation/swiftui/lazyvgrid
它的工作方式与 List
类似,但它将每个项目都放在一个列网格中。
使用它可以为您解决这个问题。
没有LazyVGrid
如果您真的不想使用 LazyVGrid
(尽管请使用它)。那么您使用的计算不正确。计算类似于...
index = row*numberOfCols + column
您不能只使用该行,因为这只会使每行的索引增加 1。但是您需要将索引增加每行的列数(在您的情况下为 2)。
我正在为我的小部件扩展使用 4 块网格。
我想用一组元素填充这些网格。
let exampleArray = ["test1","test2","test3","test4"]
当我使用两个嵌套的 ForEach 循环时,我无法获取第 4 个索引中的元素。
VStack {
ForEach((0..<2)) { column in
HStack {
ForEach((0..<2)) { index in
ZStack (alignment: .bottomLeading) {
Text(newsList[(index+column)]) // 0+0, 1+0, 0+1, 1+1
// Text = test1, test2, test2, test3
}
}
}
}
}
有什么办法可以解决这个问题吗?因为它在View
,我无法使用任何操作
视图的完整代码:
struct AppWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily)
var widgetFamily
var body: some View {
VStack(alignment: .trailing, spacing: 6) {
Image("logo")
.frame(maxWidth: .infinity, alignment: .leading)
if widgetFamily == .systemLarge {
VStack {
ForEach((0..<2)) { column in
HStack {
ForEach((0..<2)) { index in
ZStack (alignment: .bottomLeading) {
if let url = URL(string: imageList[(index+column)]), let imageData = try? Data(contentsOf: url),
let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
} else {
Image("ph_background")
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
}
Text(newsList[(index+column)])
.font(.system(size: 12))
.foregroundColor(.white)
.fontWeight(.light)
// .frame(maxHeight: 50)
.background(Rectangle().fill(Color.black).blur(radius: 20))
.padding(.bottom, 5)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.top, 5)
}
}
}
}
}
}
}
}
解决方案 请检查已接受的答案。
struct AppWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily)
var widgetFamily
var body: some View {
var columns: [GridItem] =
Array(repeating: .init(.fixed(100)), count: 2)
if widgetFamily == .systemLarge {
LazyVGrid(columns: columns) {
ForEach((0..<4)) { index in
ZStack (alignment: .bottomLeading) {
if let url = URL(string: imageList[(index)]), let imageData = try? Data(contentsOf: url),
let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
} else {
Image("ph_background")
.centerCropped()
.frame(maxHeight: 150, alignment: .center)
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1))
.shadow(radius: 10)
}
Text(newsList[(index)])
.font(.system(size: 12))
.foregroundColor(.white)
.fontWeight(.light)
// .frame(maxHeight: 50)
.background(Rectangle().fill(Color.black).blur(radius: 20))
.padding(.bottom, 5)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.top, 5)
}
}
}
}
}
}
使用LazyVGrid
我觉得你真的应该为此使用 LazyVGrid
...
https://developer.apple.com/documentation/swiftui/lazyvgrid
它的工作方式与 List
类似,但它将每个项目都放在一个列网格中。
使用它可以为您解决这个问题。
没有LazyVGrid
如果您真的不想使用 LazyVGrid
(尽管请使用它)。那么您使用的计算不正确。计算类似于...
index = row*numberOfCols + column
您不能只使用该行,因为这只会使每行的索引增加 1。但是您需要将索引增加每行的列数(在您的情况下为 2)。