根据SwiftUI中的内容做一个VStack高度
Make a VStack height according to content in SwiftUI
我想制作一张“卡片”,但高度取决于项目列表,我不知道如何根据我的尺寸列表设置不同的值...示例:
ContentView 结构
struct ContentView: View {
@State private var orderList : [Order] = [
Order(id: 0, productList: [Product(id: 0, name: "itemA", quantity: "24", isEvaluated: true), Product(id: 0, name: "itemB", quantity: "2", isEvaluated: false)]),
Order(id: 1, productList: [Product(id: 0, name: "itemC", quantity: "4", isEvaluated: true), Product(id: 0, name: "itemD", quantity: "12", isEvaluated: false),Product(id: 0, name: "itemE", quantity: "6", isEvaluated: false), Product(id: 0, name: "itemF", quantity: "5", isEvaluated: false)]),
Order(id: 2, productList: [Product(id: 0, name: "itemG", quantity: "24", isEvaluated: true)]),
Order(id: 3, productList: [Product(id: 0, name: "itemH", quantity: "5", isEvaluated: true), Product(id: 0, name: "itemI", quantity: "2", isEvaluated: false),Product(id: 0, name: "itemJ", quantity: "16", isEvaluated: false), Product(id: 0, name: "itemK", quantity: "4", isEvaluated: false), Product(id: 0, name: "itemL", quantity: "2", isEvaluated: false)]),
Order(id: 4, productList: [Product(id: 0, name: "itemM", quantity: "8", isEvaluated: true)])
]
var body: some View {
VStack{
ForEach(orderList, id: \.self){order in
ScrollView(showsIndicators: false){
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Total")
Spacer()
Text("[=10=].00")
}
Spacer()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.padding(10)
}
.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
func getProduct(productList: [Product], index: Int)-> Product{
return productList[index]
}
}
ItemRow 结构
struct ItemRow: View {
let currentProduct: Product
init(_ currentProduct: Product) {
self.currentProduct = currentProduct
}
var body: some View {
HStack{
HStack{
Text("• \(currentProduct.name)")
Spacer()
}
HStack{
Text("quantity \(currentProduct.quantity)")
Spacer()
}
if !currentProduct.isEvaluated{
HStack{
Spacer()
Button(action:{
// do sth
}){
Text("rate now!")
}
}
}
}
}
}
PS。在 itemsList 中,您必须创建一个名为 Order
的 struct
,如下所示:(不要介意硬编码值,我这样做是为了让示例更简单)
struct Order: Hashable {
var id: Int
var productList: [Product]
}
PS2。在 productList 中,您必须创建一个名为 Product
的 struct
,如下所示:
struct Product: Hashable {
var id: Int
var name: String
var quantity : String
var isEvaluated : Bool
}
如果我对你的理解是正确的,你希望卡片(红框)占用尽可能多的space,因为它们不需要在卡片本身上滚动就可以显示它们拥有的内容?
简答。你不需要。
SwiftUI 为您代劳。 ContentView
中你的代码只有一个小错误。将 ScrollView
向上移动到 VStack
所在的层级并删除 VStack
。您 ContentView
body
现在应该看起来像这样:
var body: some View {
ScrollView {
ForEach(orderList, id: \.self){order in
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Total")
Spacer()
Text("[=10=].00")
}
Spacer()
}.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
结果如下:
我想制作一张“卡片”,但高度取决于项目列表,我不知道如何根据我的尺寸列表设置不同的值...示例:
ContentView 结构
struct ContentView: View {
@State private var orderList : [Order] = [
Order(id: 0, productList: [Product(id: 0, name: "itemA", quantity: "24", isEvaluated: true), Product(id: 0, name: "itemB", quantity: "2", isEvaluated: false)]),
Order(id: 1, productList: [Product(id: 0, name: "itemC", quantity: "4", isEvaluated: true), Product(id: 0, name: "itemD", quantity: "12", isEvaluated: false),Product(id: 0, name: "itemE", quantity: "6", isEvaluated: false), Product(id: 0, name: "itemF", quantity: "5", isEvaluated: false)]),
Order(id: 2, productList: [Product(id: 0, name: "itemG", quantity: "24", isEvaluated: true)]),
Order(id: 3, productList: [Product(id: 0, name: "itemH", quantity: "5", isEvaluated: true), Product(id: 0, name: "itemI", quantity: "2", isEvaluated: false),Product(id: 0, name: "itemJ", quantity: "16", isEvaluated: false), Product(id: 0, name: "itemK", quantity: "4", isEvaluated: false), Product(id: 0, name: "itemL", quantity: "2", isEvaluated: false)]),
Order(id: 4, productList: [Product(id: 0, name: "itemM", quantity: "8", isEvaluated: true)])
]
var body: some View {
VStack{
ForEach(orderList, id: \.self){order in
ScrollView(showsIndicators: false){
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Total")
Spacer()
Text("[=10=].00")
}
Spacer()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.padding(10)
}
.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
func getProduct(productList: [Product], index: Int)-> Product{
return productList[index]
}
}
ItemRow 结构
struct ItemRow: View {
let currentProduct: Product
init(_ currentProduct: Product) {
self.currentProduct = currentProduct
}
var body: some View {
HStack{
HStack{
Text("• \(currentProduct.name)")
Spacer()
}
HStack{
Text("quantity \(currentProduct.quantity)")
Spacer()
}
if !currentProduct.isEvaluated{
HStack{
Spacer()
Button(action:{
// do sth
}){
Text("rate now!")
}
}
}
}
}
}
PS。在 itemsList 中,您必须创建一个名为 Order
的 struct
,如下所示:(不要介意硬编码值,我这样做是为了让示例更简单)
struct Order: Hashable {
var id: Int
var productList: [Product]
}
PS2。在 productList 中,您必须创建一个名为 Product
的 struct
,如下所示:
struct Product: Hashable {
var id: Int
var name: String
var quantity : String
var isEvaluated : Bool
}
如果我对你的理解是正确的,你希望卡片(红框)占用尽可能多的space,因为它们不需要在卡片本身上滚动就可以显示它们拥有的内容?
简答。你不需要。
SwiftUI 为您代劳。 ContentView
中你的代码只有一个小错误。将 ScrollView
向上移动到 VStack
所在的层级并删除 VStack
。您 ContentView
body
现在应该看起来像这样:
var body: some View {
ScrollView {
ForEach(orderList, id: \.self){order in
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("[=10=].00")
}
HStack{
Text("Total")
Spacer()
Text("[=10=].00")
}
Spacer()
}.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
结果如下: