xcode动态改变窗口大小_[SwiftUI 100天] 在 SwiftUI 中动态过滤 @FetchRequest
译自 https://www.hackingwithswift.com/books/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 ➕三连?关注专栏,关注我
在 SwiftUI 中动态过滤 @FetchRequest
对于 SwiftUI ,我经常被问到的一个问题是:我要怎么样动态地改变一个 Core Data@FetchRequest
,以便使用不同的谓词或者排序呢?大家之所以会提出这个问题是因为 fetch 请求是作为属性被创建的,因此如果你尝试让它们引用另外的属性,会被 Swift 拒绝。
这里有一个简单的解决方案,而且你回想的话会发现这其实是非常明显的方案:因为几乎所有其他东西也是这么运作的:我们应该把这个功能分割到一个独立的视图,然后把值注入进去。
我想用一些实际的代码来说明,所以我在下面放了一些最简单的例子:添加三个歌手到 Core Data,然后用两个按钮分别显示姓以 A 或者 S 结尾的歌手。
创建一个叫 Singer 的 Core Data 实体,给它两个字符串书写:“firstName” 和 “lastName”。用数据模型检视器把它的 Codegen 改成 Manual/None,然后进入 Editor 菜单,选择 Create NSManagedObject Subclass 以便我们得到一个可以自定义的Singer
类。
等 Xcode 为我们生成好文件,打开 Singer+CoreDataProperties.swift,然后添加下面两个属性,让这个类能更好地配合 SwiftUI 使用:
var wrappedFirstName: String {firstName ?? "Unknown"
}var wrappedLastName: String {lastName ?? "Unknown"
}
接下来是实际的工作。
接下来是设计一个托管我们的信息的视图。像我之前说过的,它会有两个按钮,改变视图信息的过滤器,还有一个用于插入测试数据的按钮。
首先,添加两个属性到 ContentView
结构体,以便我们有能够保持对象的托管对象上下文,以及一个作为过滤器使用的状态:
@Environment(.managedObjectContext) var moc
@State private var lastNameFilter = "A"
对于视图的body
,我们会用一个VStack
包裹三个按钮,再加上一个放匹配的歌手列表的注释占位:
VStack {// list of matching singersButton("Add Examples") {let taylor = Singer(context: self.moc)taylor.firstName = "Taylor"taylor.lastName = "Swift"let ed = Singer(context: self.moc)ed.firstName = "Ed"ed.lastName = "Sheeran"let adele = Singer(context: self.moc)adele.firstName = "Adele"adele.lastName = "Adkins"try? self.moc.save()}Button("Show A") {self.lastNameFilter = "A"}Button("Show S") {self.lastNameFilter = "S"}
}
目前为止,一切都很简单,接下来是有趣的部分:我们需要替换掉// list of matching singers
这个注释,用实际的实现代替。这里不会用到@FetchRequest
注解,因为我们要在构造器里创建一个自定义 fetch 请求,但代码几乎是一样的。
创建一个叫 “FilteredList” 的 SwiftUI 视图,给它这个属性:
var fetchRequest: FetchRequest<Singer>
这个属性用来存储我们的 fetch 请求,以便我们可以在body
里遍历它。不过,我们并不马上创建它,因为我们还不知道我们要找的是什么东西。相反,我们要创建一个自定义构造器,接收一个过滤字符串,然后用这个字符串来设置fetchRequest
属性。
添加下面这个构造器:
init(filter: String) {fetchRequest = FetchRequest<Singer>(entity: Singer.entity(), sortDescriptors: [], predicate: NSPredicate(format: "lastName BEGINSWITH %@", filter))
}
这会得到一个用当前的托管对象上下文构建的 fetch 请求。因为这个视图会被用在ContentView
内部,所以我们不必为其注入托管对象上下文到环境中 —— 它会继承来自ContentView
的上下文。
剩下的事情就是完成视图的body
,这里唯一有趣的事情是,没有了@FetchRequest
,我们需要访问fetchRequest
的wrappedValue
属性来拉出我们的数据。因此,视图的body
实现如下:
var body: some View {List(fetchRequest.wrappedValue, id: .self) { singer inText("(singer.wrappedFirstName) (singer.wrappedLastName)")}
}
如果你不喜欢使用fetchRequest.wrappedValue
,可以创建一个简单的计算属性:
var singers: FetchedResults<Singer> { fetchRequest.wrappedValue }
至于FilteredList
的预览,你可以直接移除。
这样一来视图就完成了,我们可以回到ContentView
,把注释用实际的代码实现,如下:
FilteredList(filter: lastNameFilter)
运行应用尝试下:点击 Add Examples 按钮先创建三个歌手,然后点击 “Show A” 或者 “Show S” 来触发不同的姓氏过滤。你应该会看到列表随着你点击不同的按钮,动态更新不同的数据。
为了让这一切工作,用到一点新的知识,但算不上难 —— 只要你以 SwiftUI 的方式思考,答案会跃然纸上。
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~
xcode动态改变窗口大小_[SwiftUI 100天] 在 SwiftUI 中动态过滤 @FetchRequest相关推荐
- xcode动态改变窗口大小_详细的理论要点+3个经典案例,帮助你深入理解动态面板...
什么是动态面板 动态面板是Axure的高级交互元件,由不同的状态面板组成,是我们制作交互过程中运用频率最高的元件,很多交互效果需要依赖动态面板实现.动态面板的状态面板就像是一个容器,我们可以在里面放置 ...
- Electron无边框窗口(最小化、最大化、关闭、拖动)以及动态改变窗口大小
文章目录 一.目标原型 1. 目标 2. 原型设计 3. 原型初步实现 二.无边框窗口 1. 要点 2. 改造 三.可拖拽区 1. 要点 2. 改造 四.最小化.最大化.关闭 1. 要点 2. 改造 ...
- 动态改变标题_插入控件-gt;引用变量-gt;实现动态图表纵横筛选
欢迎关注我的微信公众号:HR爱玩儿Excel和PPT,分享有趣又有逼格的Excel和PPT创意和技巧,emmm...不关注也没有关系...哼 昨晚没睡好,因为睡前老友跟我说了句话: 我们总部做的表没有 ...
- tablayout 动态改变标题_描点法画函数图像的动态演示——动态数学软件GeoGebra制作教程...
描点法画函数图像的步骤有: 列表 描点 连线 本文以制作一次函数 y=kx+b (k≠0)为例,先看效果: 觉得还不错的话,一起动手制作吧! 制作前 由于多个滑动条需设置为"递增(一次)&q ...
- 动态改变标题_小米相册更新,新增动态换天/赛博朋克/MIUI12界面等等!
嗨咯,各位小伙伴们大家晚上好呀,今天为大家介绍一款灰度测试应用"MIUI相册"也就是大家小米手机里面的相册app,为方便解说,以下统称为"相册"更新后打开相册第 ...
- 动态改变类名_反调试之检测类名与标题名
本文内容分为两部分: 1.介绍涉及到的API 2.实践 涉及到的API函数的学习: 1.GetProcAddress 定义:GetProcAddress是一个计算机函数,功能是检索指定的动态链接库(D ...
- jq动态改变路径_在react中使用jQuery动态更改图片路径遇到的问题
您好.如题.我在代码中是这样写的. step:1 为了将默认的小图片列表从上方移到左边,我设置了template Viewer.TEMPLATE = ( ' ' + ' ' ' + ' ' ' + ' ...
- java按钮改变窗口大小_布局似乎有问题,JButton在调整窗口大小时显示出意外的行为。...
很好的例子的问题可能与平台有关,但我可以提供一些观察:您没有添加或删除组件,所以您不需要revalidate(). 由于背景色是按钮的绑定属性,因此不需要后续调用repaint(). 你,你们做需要r ...
- javascript动态改变窗口大小
var w = document.body.offsetWidth ; var h = document.body.offsetHeight + 20; self.resizeTo(w,h); 转载 ...
- unity图片变成马赛克如何取像素并改变颜色_聊聊 2D 游戏的像素化中的问题
来indienova官网,挖掘独立游戏的更多乐趣 引言 既然我是在做像素游戏,这次就聊一聊在对 2D 游戏像素化的过程中都会碰到的问题吧. 1. 照相机的投影 对于引擎来说,其实不管是 2D 游戏还是 ...
最新文章
- python中ttk和tkinter_Python tkinter与ttk日历
- 见到了“公司”定义一个Company类,那么见到了“字段”是不是也可定义一个Column类?...
- 12JavaScript中的内置对象
- 4.2 深层网络中的前向传播-深度学习-Stanford吴恩达教授
- Asp.Net数据库编程-10条最优方法[翻译]
- 计算机网络(谢希仁第八版)第一章:概述
- SmartNews:基于 Flink 加速 Hive 日表生产的实践
- [图]罗技推出背光键盘
- python是干什么用的-python是做什么用的 python有什么用 - 驱动管家
- Android - 资源(resource)转换为String
- 初识B/S结构编程技术
- 做Meta分析要用哪些软件?Meta分析软件盘点,含软件安装包!
- svn命令行回滚到指定版本
- URI和URL、URN的作用和区别
- 分享Canvas画横断面图的vue源码
- egret引擎p2物理引擎(2) - 小球碰撞地面搞笑的物理现象
- 9、智能化WebUI自动化测试框架recheck-web实战
- AD9361参数设置总结
- postman获取返回值及tests[]用法
- 屏幕录制方法?如何在电脑进行屏幕录制