我正在努力解决以下问题:我正在try 构建一个非常简单的应用程序,它允许您在一个可以折叠的专用视图中添加项目.我设法编写了一个简单的函数,使我可以添加多个这样的定制可折叠视图.这是我的第一个应用程序,所以我想遵循MVVM协议.我想我一路上都搞混了,因为现在我添加的每个项目都会自动添加到我创建的所有自定义可折叠视图中.有什么办法可以解决这个问题吗?我以为使用UUID可以解决这个问题..我猜我必须定制"saveButtonPressed"函数,但我不知道如何告诉它只将项目添加到我按下"加号"按钮的视图中.

以下是各个项目和可折叠视图的模型:

struct ItemModel: Identifiable, Equatable {
let id: String
let title: String

init(id: String = UUID().uuidString, title: String) {
    self.id = id
    self.title = title

 }

  func updateCompletion() -> ItemModel {
  return ItemModel(id: id, title: title)
   }
   }

-

import Foundation

struct CollapsableItem: Equatable, Identifiable, Hashable {
let id: String
var title: String

init(id: String = UUID().uuidString, title: String) {
    self.id = id
    self.title = title

    
}

    func updateCompletion() -> CollapsableItem {
return CollapsableItem(id: id, title: title)
    }
}

以下是我的两个视图模型:

class ListViewModel: ObservableObject  {
@Published var items: [ItemModel] = []

init() {
    getItems()
}

func getItems() {
    let newItems = [
        ItemModel(title: "List Item1"),
        ItemModel(title: "List Item2"),
        ItemModel(title: "List Item3"),
    ]
    items.append(contentsOf: newItems)
    }

func addItem(title: String) {
    let newItem = ItemModel(title: title)
    items.append(newItem)
}

func updateItem(item: ItemModel) {
    
    if let index = items.firstIndex(where: { $0.id == item.id}) {
        items[index] = item.updateCompletion()
    }
    }
    }

-

class CollapsedViewModel: ObservableObject  {
@Published var collapsableItems: [CollapsableItem] = []

@Published var id = UUID().uuidString


init() {
    getCollapsableItems()
}


func getCollapsableItems() {
    let newCollapsableItems = [
        CollapsableItem(title: "Wake up")
    ]
    collapsableItems.append(contentsOf: newCollapsableItems)
}

func addCollapsableItem(title: String) {
    let newCollapsableItem = CollapsableItem(title: title)
    collapsableItems.append(newCollapsableItem)
}




func updateCollapsableItem(collapsableItem: CollapsableItem) {
    
    if let index = collapsableItems.firstIndex(where: { $0.id == 
collapsableItem.id}) {
        collapsableItems[index] = 
 collapsableItem.updateCompletion()
    }
}

 }

项目视图:

struct ListRowView: View {
@EnvironmentObject var listViewModel: ListViewModel
let item: ItemModel

var body: some View {
    HStack() {

        
        Text(item.title)
            .font(.body)
            .fontWeight(.bold)
            .foregroundColor(.white)
            .multilineTextAlignment(.center)
            .lineLimit(1)
            .frame(width: 232, height: 16)

        
    }
    .padding( )
    .frame(width: 396, height: 56)
    .background(.gray)
    .cornerRadius(12.0)

}
}

可折叠的视图:

struct CollapsedView2<Content: View>: View {
@State var collapsableItem: CollapsableItem
@EnvironmentObject var collapsedViewModel: CollapsedViewModel
@State private var collapsed: Bool = true
@EnvironmentObject var listViewModel: ListViewModel
@State var label: () -> Text
@State var content: () -> Content
@State private var show = true

var body: some View {
    ZStack{
        VStack {
            HStack{
                Button(
                    action: { self.collapsed.toggle() },
                    label: {
                        HStack() {
                            Text("Hello")
                                .font(.title2.bold())
                            Spacer()
                            Image(systemName: self.collapsed ? "chevron.down" : 
                       "chevron.up")
                        }
                        .padding(.bottom, 1)
                        .background(Color.white.opacity(0.01))
                    }
                )
                .buttonStyle(PlainButtonStyle())
                
                
                Button(action: saveButtonPressed, label: {
                    Image(systemName: "plus")
                        .font(.title2)
                        .foregroundColor(.white)
                })
            }
            VStack {
                self.content()
            }
            
            ForEach(listViewModel.items) { item in ListRowView (item: item)
                
            }
            .lineLimit(1)
            .fixedSize(horizontal: true, vertical: true)
            .frame(minWidth: 396, maxWidth: 396, minHeight: 0, maxHeight: collapsed ? 
            0 : .none)
            .animation(.easeInOut(duration: 1.0), value: show)
            .clipped()
            .transition(.slide)
            
        }
    }
    
}
func saveButtonPressed() {
    listViewModel.addItem(title: "Hello")
}
        }
        
            

最后是主要观点:

struct ListView: View {

@EnvironmentObject var listViewModel: ListViewModel
@EnvironmentObject var collapsedViewModel: CollapsedViewModel

var body: some View {
    ZStack{
            ScrollView{
                VStack{
                    HStack{
                        Text("MyFirstApp")
                            .font(.largeTitle.bold())
                        
                        Button(action: newCollapsablePressed, label: {
                            
                            Image(systemName: "plus")
                                .font(.title2)
                                .foregroundColor(.white)
                            
                        })
                    }
                    .padding()
                    .padding(.leading)
                    
                    ForEach(collapsedViewModel.collapsableItems) { collapsableItem in 
                    CollapsedView2 (collapsableItem: collapsableItem,                      
                    label: { Text("") .font(.title2.bold()) },
                                                                                                      
                    content: {
                        
                        HStack {
                            Text("")
                            Spacer() }
                        .frame(maxWidth: .infinity)
                        
                        
                    })
                        
                        
                        
                    }
                    .padding()
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .statusBar(hidden: false)
            .navigationBarHidden(true)
        }
}

func newCollapsablePressed() {
    collapsedViewModel.addCollapsableItem(title: "hello2")
}
}


       

我很想知道我怎么才能解决这个问题!

推荐答案

在每个折叠式视图2中都有您对添加项目的 comments 的Anwser. 因为ListViewModel不是ObservableObject(ListViewModel与每个ColupsableItem都不同).您应该使用"@State var Items:[ItemModel]".

struct CollapsedView2<Content: View>: View {
    @State var collapsableItem: CollapsableItem
//    @State var listViewModel = ListViewModel()
    @State var collapsed: Bool = true
    @State var label: () -> Text
    @State var content: () -> Content
    @State private var show = true
    @State var items: [ItemModel] = []
    @State var count = 1

    var body: some View {
            VStack {
                HStack{
                    Text("Hello")
                        .font(.title2.bold())
                    
                    Spacer()
                    
                    Button( action: { self.collapsed.toggle() },
                            label: {
                        Image(systemName: self.collapsed ? "chevron.down" : "chevron.up")
                    }
                    )
                    .buttonStyle(PlainButtonStyle())

                    Button(action: saveButtonPressed, label: {
                        Image(systemName: "plus")
                            .font(.title2)
//                            .foregroundColor(.white)
                    })
                }
                VStack {
                    self.content()
                }

                ForEach(items) { item in
                    ListRowView (item: item)
                }
                .lineLimit(1)
                .fixedSize(horizontal: true, vertical: true)
                .frame(minHeight: 0, maxHeight: collapsed ? 0 : .none)
                .animation(.easeInOut(duration: 1.0), value: show)
                .clipped()
                .transition(.slide)
            }
    }

    func saveButtonPressed() {
        addItem(title: "Hello \(count)")
        count += 1
    }
    
    func addItem(title: String) {
        let newItem = ItemModel(title: title)
        items.append(newItem)
    }

    func updateItem(item: ItemModel) {

        if let index = items.firstIndex(where: { $0.id == item.id}) {
            items[index] = item.updateCompletion()
        }
    }
}

Ios相关问答推荐

SwiftUI中ForEach和@ State数组的可能并发问题

为什么Reaction-Native-Vision-Camera不能与闪光灯一起使用?

无法在所有窗口上方显示图像

如何在iOS 17中拦截UITextView中的链接点击?UITextItemInteraction已弃用

iOS 17-在Xcode 15中添加导航控制器时,导航栏不会立即显示

如何使用自定义数据源在本地react 本机 ios 应用程序中加载 Tradingview 小部件?

NumberFormatter 无法使用 Xcode 15.0 beta 正确识别 iOS 17 beta 中的 Locale 货币设置

查找东南亚语言(泰语、高棉语、老挝语、缅甸语)中的单词边界

无法从 Xcode 获取模拟器列表.请打开 Xcode 并try 直接从那里运行项目以解决剩余问题

Swift/iOS:泛型错误:协议需要嵌套类型V;你想添加它吗?

Xcode 不支持 iOS 15.6

Text() 正在添加额外的前导尾随填充 SwiftUI

如何让我的 iOS 应用程序与 api 连接?

如何设置imageView的圆角半径?

未找到签名证书​​iOS Distribution

在 Swift 中将 HTML 转换为纯文本

如何获取 iTunes 连接团队 ID 和团队名称?

为给定的 UIColor 获取更亮和更暗的 colored颜色 变化

模态视图控制器 - 如何显示和关闭

为什么 UITableViewAutomaticDimension 不起作用?