• 一行代码解决CoreData托管对象属性变更在SwiftUI中无动画效果的问题


    在这里插入图片描述

    概述

    在CoreData后台支持的SwiftUI项目中,为了简化实现,我们可以直接用托管对象的属性作为SwiftUI视图状态改变的驱动器。

    不过,这样做可能会导致托管对象属性改变时没有动画效果:

    在这里插入图片描述

    如上图所示,通知时间面板视图的展开是由CoreData托管对象的属性变更触发的,但我们即使在代码中用 withAnimation 块包裹属性变更代码,仍然没有动画效果。

    如何解决呢?

    其实,只需一行代码即可搞定!

    So,别再等待,Let‘s Fix It!😉

    一行代码!

    首先,来看一下源代码:

    extension Item {
    
        @nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
            return NSFetchRequest<Item>(entityName: "Item")
        }
    
        @NSManaged public var enableNotify: Bool
    }
    
    struct ItemInfoView: View {
    	@EnvironmentObject var item: Item
    	 
    	var body: some View {
    		VStack {
    			Button(action: {
                    withAnimation {
                    	// 变更托管对象item的enableNotify属性
                        item.enableNotify.toggle()
                    }
                    
                    model.moc.saveIfNeed()
                }){
                    Image(systemName: "bell.circle")
                        .foregroundColor(item.enableNotify ? .blue : .gray)
                }
    
    			if item.enableNotify {
    				// 显示提醒时间面板...
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    虽然我们将item对象用 @EnvironmentObject 修饰,希望可以有动画反馈,但实际并没有任何事情发生。

    其实,遇到这种情况,我们只需显式托管对象本身发送变更通知即可。

    因为CoreData的任何托管类都遵守ObservableObject协议,即它的实例都包含一个名为objectWillChange的发布器对象,我们只需让其发送消息,即可驱动SwiftUI视图刷新从而产生动画效果:

    Button(action: {
        withAnimation {
            item.enableNotify.toggle()
            // 显式刷新界面,触发动画
            item.objectWillChange.send()
        }
        
        model.moc.saveIfNeed()
    }){
        Image(systemName: "bell.circle")
            .foregroundColor(item.enableNotify ? .blue : .gray)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    现在,我们再来看一下运行效果:

    在这里插入图片描述

    久违的动画再次回归,棒棒哒!💯

    题外话

    本篇博文所述问题很简单,很快就搞定了!

    我们再来聊一个Xcode开发CoreData项目中的小技巧。

    一般来说,我们在Xcode中对于CoreData托管类总是采用自动生成的配置方法(即Class Definition):

    在这里插入图片描述

    这时,Xcode会为我们自动生成托管类的定义,有的小伙伴可能想看一下实际生成托管类的代码,却不知何去何从。

    这里教大家一招,按住option键,鼠标左键在任意托管对象类名上点击,然后在弹出的浮动小窗口上点击底部蓝色的 托管类名+CoreDataClass.swift 文本:

    在这里插入图片描述

    此时,Xcode会跳转到该托管类的定义文件中去:

    在这里插入图片描述

    最后,鼠标右键点击Xcode托管类文件窗口顶部的文件名,即可展现其实际的存放路径:

    在这里插入图片描述

    点击对应的目录项,即可在Finder中打开。里面存放着所有Xcode自动生成的托管类定义文件。

    总结

    在本篇博文中,我们仅用一行代码就解决了CoreData托管对象属性变更无法触发SwiftUI视图动画的问题;我们还顺便介绍了如何快速查看Xcode自动生成CoreData托管类的定义文件。

    小伙伴们是不是觉得很简单呢?

    最后,感谢大家观赏,再会!😎

  • 相关阅读:
    俄罗斯方块
    (入门自用)--Linux--文件系统--磁盘--1019
    elementui实现表格(el-table)默认选中
    统计专业人员职称评价基本标准
    Java开发学习(十五)----AOP入门案例及其工作流程解析
    接口测试实战讲解
    Java解析MDB(上)-纯JDBC解析非空间数据
    Kafka 技术指南:使用、特性、一致性保证与 Golang 中间件应用(上)
    【金三银四】Java基础知识面试题(2021最新版)
    题目0049-N进制减法
  • 原文地址:https://blog.csdn.net/mydo/article/details/126076971