SwiftUI 中创建一个自定义文件管理器只需4步!你敢信!?

在这里插入图片描述

概览

在 SwiftUI 中写一个自定义文件内容的管理器有多难呢?

在这里插入图片描述

答案可能超乎小伙伴们的想象:仅需4步!可谓是超级简单!

在本篇博文中,您将学到如下内容:

  • 概览
  • 1. 第一步:定义文件类型
  • 2. 第二步:创建文件新建/编辑界面
  • 3. 第三步:DocumentGroup 为您解忧 !
  • 4. 第四步:快使用系统文件浏览器(System’s Document Browser)
  • 总结

还等什么呢?Let‘s go!go!go!😉


1. 第一步:定义文件类型

为了将 App 无缝集成到文件管理器中,我们首先需要创建自己的文件类型。

根据应用功能的复杂程度,我们的自定义文件类型可以“平静如水”,也可以“惊天动地”。

在这里,我们不想搞得太过复杂而吓跑一些小伙伴们,所以一切从简:

import SwiftUI
import UniformTypeIdentifiersstruct ColorText: Codable{enum ContentColor: Codable, CaseIterable, Identifiable  {case red, green, blue, gray, orangevar color: Color {switch self {case .red:.redcase .gray:.graycase .green:.greencase .blue:.bluecase .orange:.orange}}var id: Color {color}}// 自定义文件中包括文本和文本对应的颜色,仅此而已var text = ""var color = ContentColor.red
}struct PandaTextFile: FileDocument {static var readableContentTypes = [UTType.data]// 文件名var name: String?var content: ColorTextinit(initialText: String = "", color: ColorText.ContentColor = .red) {content = .init(text: initialText, color: color)}// 自定义文件的解码init(configuration: ReadConfiguration) throws {guard let data = configuration.file.regularFileContents else {throw CocoaError(.fileReadCorruptFile)}name = configuration.file.filenamelet decoder = JSONDecoder()let colorText = try decoder.decode(ColorText.self, from: data)content = colorText}// 自定义文件的编码func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {let data = try JSONEncoder().encode(content)return FileWrapper(regularFileWithContents: data)}
}// 为预览而生!
extension PandaTextFile {static var preview: PandaTextFile {.init(initialText: "Hello,大熊猫侯佩!")}
}

如上所示,我们在自定义文件中保存了文本和文本对应的颜色,仅此而已。

2. 第二步:创建文件新建/编辑界面

在自定义文件类型“羽翼丰满”之后,接下来是写一个与其对应的新建和编辑界面。它起到“承上启下” 后面 DocumentGroup 的重要作用:

import SwiftUIstruct NewPandaTextFileView: View {@Binding var document: PandaTextFilevar body: some View {NavigationStack {VStack {TextEditor(text: $document.content.text).font(.title3.weight(.bold)).foregroundStyle(document.content.color.color)Grid(horizontalSpacing: 16) {GridRow {ForEach(ColorText.ContentColor.allCases) { cc incc.color.frame(width: 50, height: 50).border(document.content.color == cc ? .black : .clear, width: 5).onTapGesture {document.content.color = cc}}}}}.padding().navigationTitle("🐼 \(document.name ?? "无名文件")")}}
}struct Preview: View {@State var file = PandaTextFile.previewvar body: some View {NewPandaTextFileView(document: $file)}
}#Preview {Preview()
}

在完成了 NewPandaTextFileView 之后,我们可以立即在 Xcode 预览中一睹它的真容:

在这里插入图片描述

3. 第三步:DocumentGroup 为您解忧 !

有了自定义文件类型和对应的编辑视图之后,我们随即可以将他们和 DocumentGroup “无缝”的连接起来。

在这里插入图片描述
简单来说,DocumentGroup 是一个可以用于打开、创建以及保存文档的 Scene。

我们可以将它直接嵌入到 App 结构中代替 WindowGroup 来构建一个基于文档应用的宏观布局:

import SwiftUI@main
struct DocBasedAppDemoApp: App {var body: some Scene {DocumentGroup(newDocument: PandaTextFile()) { file inNewPandaTextFileView(document: file.$document)}}
}

可以看到:在 DocumentGroup 闭包中我们将之前创建的 NewPandaTextFileView 文件编辑视图作为自定义文档的 editor ,水到自然渠成!Nice!!!

init(newDocument: @autoclosure @escaping () -> Document,@ViewBuilder editor: @escaping (FileDocumentConfiguration<Document>) -> Content
)

4. 第四步:快使用系统文件浏览器(System’s Document Browser)

在用 DocumentGroup “串联”一切之后,我们只差一步!

我们只需要对系统说:“请把我融入您文件浏览器宽广的胸怀中去吧”,即可享受它带给我们关于文档管理上的“解囊相助”。

进入 Xcode 中项目目标的 info 窗口,新建一个名为 “Supports Document Browser” 的键,并将其值设置为 Yes:

在这里插入图片描述

确保操作无误后,最后运行 App 感受一下系统文件浏览器给我们带来的“如虎添翼”:

在这里插入图片描述

仅仅 4 步之后,一个小巧且“五脏六腑俱全”的文件管理器跃然而出了!小伙伴们给自己点一个大大的赞吧!!!棒棒哒💯


更多 SwiftUI 自定义文件管理器的相关实现,请小伙伴们移步如下链接进一步观赏:

  • SwiftUI 实现一个 iOS 上 Files App 兼容的文件资源管理器

总结

在本篇博文中,我们讨论了如何在 SwiftUI 中仅需 4 步就完成一个“麻雀虽小却五脏俱全”的自定义文件管理器,相信学完本课小伙伴们都会受益良多。

感谢观赏,再会!😎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/255851.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能优化算法应用:基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工大猩猩部队算法4.实验参数设…

python六子棋ai对战(alpha-beta)剪枝算法

核心代码 def __init__(self): #初始化函数self.num0 #对yi次数self.rows 10 #初始化棋盘10行self.cols 10 # 初始化棋盘10列self.rank6 #阶数 代表六子棋self.empty_board() #清空棋盘self.V 10 #攻击程度self.E10 #防守程度self.depth2 #思考深度…

嵌入式板级系统设计【课设】

笔记【嵌入式板级系统设计】 前言版权笔记【嵌入式板级系统设计】资料学习面包板焊接注意焊接教程 焊接电路板基础代码GPIO 外部中断 定时中断 三合一串口 综合实验 风扇控制系统下板三合一窗口综合实验 最后 前言 2023-11-20 08:49:57 以下内容源自《【创作模板五】》 仅供学…

【AIGC】prompt工程从入门到精通

注&#xff1a;本文示例默认“文心大模型3.5”演示&#xff0c;表示为>或w>&#xff08;wenxin)&#xff0c;有时为了对比也用百川2.0展示b>&#xff08;baichuan) 有时候为了模拟错误输出&#xff0c;会用到m>&#xff08;mock)表示&#xff08;因为用的大模型都会…

网络排错思路

⽹络模型 国际标准化组织制定的开放式系统互联通信参考模型&#xff08;Open System Interconnection Reference Model&#xff09;&#xff0c;简称为 OSI ⽹络模型。 为了解决⽹络互联中异构设备的兼容性问题&#xff0c;并解耦复杂的⽹络包处理流程&#xff0c;OSI 模型把…

【每日一题】重新规划路线

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;深度优先搜索方法二&#xff1a;广度优先搜索 写在最后 Tag 【深搜】【广搜】【树】【2023-12-07】 题目来源 1466. 重新规划路线 题目解读 题目给定一张由 n个点&#xff08;使用 0 到 n−1 编号&#xff09;&#…

C++ 函数详解

目录 函数概述 函数的分类 函数的参数 函数的调用 函数的嵌套调用 函数的链式访问 函数声明和定义 函数递归 函数概述 函数——具有某种功能的代码块。 一个程序中我们经常会用到某种功能&#xff0c;如两数相加&#xff0c;如果每次都在需要用到时实现&#xff0c;那…

【Java系列】函数式接口编程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

如何使用Docker本地搭建开源CMF Drupal并结合内网穿透公网访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

业绩超预期,股价却暴跌,MongoDB股票还值得投资吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 尽管MongoDB(MDB)本季度的财报超出了预期&#xff0c;并提高了全年预期&#xff0c;但它的股价在财报发布后还是出现了暴跌。 MongoDB截至2023年10月31日的第三财季&#xff0c;收入同比增长了30%&#xff0c;达到了4.329亿…

HXDSP2441-地址空间转换

地址空间转换 地址空间本身很简单&#xff0c;但由于HXDSP2441同时有DSP核和CPU核&#xff0c;且二者寻址方式不同&#xff0c;导致编程中会有歧义。 DSP核采用字地址编址方式&#xff0c;CPU核和总线空间内都采用字节地址编址方式&#xff0c;而且文档中所涉及的所有寄存器地…

选择更好的Notes索引附件方式

大家好&#xff0c;才是真的好。 首先介绍最近产品更新消息。在上一周&#xff0c;HCL主要发布了以下几个产品更新&#xff1a;HCL Verse 3.2.0、HCL Volt MX Go 2.0.2、HCL Domino Rest API 1.0.8。 HCL Verse是今后Domino的产品当中主要使用的webmail功能&#xff0c;这一次…