关闭自定义模式/覆盖不更新 SwiftUI 中的视图内容

Posted

技术标签:

【中文标题】关闭自定义模式/覆盖不更新 SwiftUI 中的视图内容【英文标题】:Dismissing custom modal / overlay not updating contents of View In SwiftUI 【发布时间】:2020-07-04 16:41:32 【问题描述】:

更新:我对其进行了一些重构以使用@ObservableObject,但问题仍然存在

在我的 SwiftUI 应用程序中,我有一个 LazyVGrid 填充有 n 个卡片和一个 New Event 按钮。当我按下 New Event 按钮时,我有一个覆盖视图的自定义模式,让用户添加一个新事件。但是,在关闭视图后(通过点击 Create Event 按钮),模式消失了,但新的事件卡并未添加到 LazyVGrid。只有在我强制退出应用并重新打开它时才会出现。

这里是主要的ContentView

struct ContentView: View 
    @State var progress: Double = 0.0
    @State var editMode: Bool = false
    @State var angle: Double = 0
    @State var showModal: Bool = false

    @ObservedObject var model: Model
            
    var columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 10), count: 2)
    
    func animate(while condition: Bool) 
        self.angle = condition ? -0.6 : 0
        
        withAnimation(Animation.linear(duration: 0.125).repeatForever(while: condition)) 
            self.angle = 0.6
        
        
        if !condition 
            self.angle = 0
        
    
    
    var body: some View 
        ZStack 
            NavigationView 
                LazyVGrid(columns: columns, spacing: 10) 
                    ForEach(model.events, id: \.self)  event in
                        SmallCardView(event: event, angle: $angle)
                    
                    
                    if !showModal 
                        AddEventButtonView(
                            editMode: $editMode,
                            showModal: $showModal,
                            namespace: namespace
                        )
                     else 
                        Spacer().frame(height: 100)
                    
                
                .onLongPressGesture 
                    if !self.editMode 
                        self.editMode = true
                        animate(while: self.editMode)
                    
                
            
            
            if self.showModal 
                AddEventView(namespace: namespace, events: self.$model.events, showModal: $showModal)
            
            
        
    

这是添加事件按钮的视图:

struct AddEventButtonView: View 
    @Binding var editMode: Bool
    @Binding var showModal: Bool
    
    var namespace: Namespace.ID

    var body: some View 
        Image(systemName: "calendar.badge.plus")
            .frame(height: 100)
            .frame(maxWidth: .infinity)
            .opacity(self.editMode ? 0.0 : 1.0)
            .onTapGesture 
                withAnimation 
                    self.showModal = true
                
            
    

这是我的模态视图:

struct AddEventView: View 
    @State var eventName: String = ""
    @State var endDate = Date()
    @State var gradientIndex: Int = 0
    
    @Binding var showModal: Bool
    @Binding var events: [Event]
    
    var namespace: Namespace.ID
    
    init(namespace: Namespace.ID, events: Binding<[Event]>, showModal: Binding<Bool>) 
        self.namespace = namespace
        self._events = events
        self._showModal = showModal
    
    
    var body: some View 
        VStack(spacing: 30.0) 
            //...
                        
            Button(action: 
                let event = Event(name: eventName, start: .init(), end: endDate, gradientIndex: gradientIndex)
                
                self.events.append(event)
                
                withAnimation 
                    self.showModal = false
                
            ) 
                RoundedRectangle(cornerRadius: 13)
                    .frame(maxWidth: .infinity)
                    .frame(height: 42)
                    .overlay(
                        Text("Add Event")
                            .foregroundColor(.white)
                            .bold()
                    )
            
            .disabled(self.eventName.isEmpty)
        
    


如果有人知道如何更新 LazyVGrid 以在添加新事件时显示新事件卡,那就太棒了,谢谢!

问题来了:

【问题讨论】:

方法可以和this solution中的一样,用于LazyVStack @Asperi 这似乎只是让新添加的元素滚动到底部,而我只是希望元素出现在网格中,它根本不需要滚动 【参考方案1】:

不清楚你是如何设置model的,但应该注意更新视图,如(scratchy)

struct ContentView: View 
    @State var progress: Double = 0.0
    @State var editMode: Bool = false
    @State var angle: Double = 0
    @State var showModal: Bool = false

    @ObservedObject var model: Model       // << here !!

...

或使用@EnvironmentObject 模式通过.environmentObject 进行注入

或者对于 Swift 2.0 使用

@StateObject var model: Model = Model.shared

【讨论】:

我实际上刚刚完成了重构以使其成为 ObservableObject!但问题仍然存在:/

以上是关于关闭自定义模式/覆盖不更新 SwiftUI 中的视图内容的主要内容,如果未能解决你的问题,请参考以下文章

OSX 中的 SwiftUI 自定义文本字段

具有自定义数据结构的 SwiftUI 列表,每个循环都嵌套 [关闭]

Swagger自定义文档插件

在 MapBox SwiftUI 中使用自定义注释图像 [关闭]

SwiftUI 自定义 List 不能在 ForEach 中使用 Binding

如何阻止 MacOS 更新覆盖我的 auto_master 文件? [关闭]