ios - Transition 不适用于嵌套在 List 中的 ForEach 以及来自 Core Data 的数据

标签 ios core-data swiftui ios-animations

为什么这个标题?

因为 ListForEachCoreData 在我看来是三大罪魁祸首……好吧,如果不是简单的 。 transition() 本身。

我想要什么

基本上我想要,比如说,存储在核心数据中的任务列表,并且在点击任务时,它会随着 .transition(.scale) 消失。我尝试过的几个潜在解决方案在 Canvas 和模拟器中都失败了,其中两个在堆栈溢出上:

  1. SwiftUI insertion transion is not working when view added
  2. Transition animation not working in SwiftUI

其余的尝试只是在所有可能的地方插入 .transition(.scale),并附加/不附加 .animation(...)


代码概览

这是我的错误 View 的基本结构:

struct DeadlineListView: View {
    @FetchRequest(entity: Deadline.entity(),
                  sortDescriptors: [NSSortDescriptor(keyPath: \Deadline.dueTime, ascending: true)],
                  predicate: NSPredicate(format: "isCompleted == false"),
                  animation: Animation.linear(duration: 2)
    ) var deadlineList: FetchedResults<Deadline>
    
    // some other vars...
    
    var body: some View {
        VStack(spacing: 0.0) {
            HStack {
                // some other views...
            }
            
            // --- Where things matter most ---
            List {
                ForEach(deadlineList, id: \.uid) { deadline in
                    Button(action: { isShowingDeadlineDetails = true }) {
                        DeadlineView(deadline: deadline)
                    }.sheet(isPresented: $isShowingDeadlineDetails) {
                        DeadlineDetailView(deadline: deadline)
                    }
                    .listRowInsets(EdgeInsets())
                }
            }
            // --- Where things matter most ---
        }
    }
}

所以从技术上讲,我有一个 Button 列表,看起来像 DeadlineView(...)

DeadlineView(...) 有一个按钮供用户点击以表示任务已完成:

Button(action: {
    deadline.isCompleted = true
    deadline.objectWillChange.send()

    do {
        try context.save()
    } catch {
        print("Unable to save deadline isCompleted in DeadlineView!")
    }
}){
    // some View...
}

此按钮将使 NSPredicate 忽略此任务,因此该任务从我的列表中消失。


我实际得到的

是的,它确实在做动画。但是完成的任务被它下面的任务挤压,没有任何可见的(至少对我来说).transition(.scale)


我放置.transition(.scale)的地方

回到第一个片段:

            List {
                ForEach(deadlineList, id: \.uid) { deadline in
                    Button(action: { isShowingDeadlineDetails = true }) {
                        DeadlineView(deadline: deadline)
                        // .transition(.scale) 1. HERE!
                    }
                    // 2. HERE!
                    .sheet(isPresented: $isShowingDeadlineDetails) {
                        DeadlineDetailView(deadline: deadline)
                    }
                    // 3. HERE!
                    .listRowInsets(EdgeInsets())
                    // 4. HERE!
                }
                // 5. HERE!
            }
            // 6. HERE!

全部带/不带 .animation(.linear(duration: 2)) 附在后面


又一个小发现

您可能已经注意到,动画 (2) 的 duration 非常长,所以它的运行速度足够慢,我可以观察到它不是 的确是过渡

但有趣的是,它不会响应 duration,无论是 0.2 还是 2(好吧,至少对我来说它不会似乎持续 2 秒)。


欢迎任何解决方案或解决方法。

最佳答案

由于过渡影响了这里的许多 View 。您必须在内部进行与过渡相关的更改

withAnimation(Animation.easeIn) { //here you can change the animation you want
               //state changes should write here
            }

此链接可能有帮助 https://www.youtube.com/watch?v=3krC2c56ceQ

关于ios - Transition 不适用于嵌套在 List 中的 ForEach 以及来自 Core Data 的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65308437/

相关文章:

ios - 使 PFQuery 只包含具有特定值的对象

swift : get the closest date stored in the core data

ios - 尝试按一个属性分组并获取核心数据中每组中的实体数

list - SwiftUI - 两个独立的按钮合二为一

ios - SwiftUI HStack 以等间距填充整个宽度

ios - 如何在特定的 indexpath.row 上显示自定义 tableviewcell

iphone - GLfloat 动态数组声明

ios - 核心数据。检测相同的对象?

xcode - SwiftUI 包装的 SearchBar 无法关闭键盘

iphone - 如何保护 iPhone 应用程序中存储的外部 Web 服务密码?