From 5b0b0325f2f2e596970276eab12616d90ee0c2a9 Mon Sep 17 00:00:00 2001 From: jackzhhuang Date: Sun, 29 Oct 2023 17:34:01 +0800 Subject: [PATCH] add index --- appledev/swfituiincocoa.html | 24 +++++++++---------- index.html | 2 +- ...270\255\344\275\277\347\224\250swiftUI.md" | 10 ++++---- "\345\246\202\345\215\223.md" | 2 ++ 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/appledev/swfituiincocoa.html b/appledev/swfituiincocoa.html index 705633c..ecbd22c 100644 --- a/appledev/swfituiincocoa.html +++ b/appledev/swfituiincocoa.html @@ -675,20 +675,20 @@ 【swift基础】在UIKit中使用swiftUI
-

Home

【swift基础】在 UIKit 中使用 swiftUI

使用 swiftUI 制作一些自定义控件还是非常方便的,但某些时候又不得不需要 UIKit。

先有一个 swiftUI 的view

假设我们有一个 swiftUI view 如下:

这是一个完整的 swiftUI。

使用NSHostingController

引入 NSHostingController

要想显示 swiftUI view,需要一个 Hosting controller 去承载,因此需要在 storyboard 中的 library 中拉一个 hosting controller 控件:

 

这个控件将会代表 swfitUI 存在于 storyboard 中。

创建 hosting controller 的类

此处当然需要一个类和 hosting controller 关联:

注意 NSHostingController 的模板类正是我们的 swiftUI 类 SettingsView,其 required init?(coder: NSCoder) 函数会调用 SettingsView 的构造函数初始化。

最后在 property 面板中将控件和类关联起来:

这样我们就可以在 UIKit 的代码中通过 SettingsHostingController 来控制一个用 swiftUI 编写的 SettingsView 了。

显示 hosting controller

显示 hosting controller 其实就是现实其关联的 swiftUI 对象。如果我们打开面板,会发现 hosting controller 有一个 action 消息叫 show 或者 modal,因此只要有人给他发 show 或者 modal 消息就可以显示 hosting controller。

这里我们把它绑定到一个 menu 上,只需要 control 拉动即可发送 show 或者 modal 消息:

show 和 modal 的区别就是前者不阻塞父 view 但后者会。

UIKit 和 swiftUI 之间的消息通信

解决了显示问题,接下来就要解决消息通讯的问题了,有了 swift 对象,应该就可以相互调用,但考虑到 UI 交互的问题,比如调整了某个变量值,这个调整动作即改变了 UI 显示也改变了后台数据,因此如果直接用对象调用的方式传递数据,有可能会阻塞 UI 显示或者有并发冲突的问题。因此, UI 之间的数据通信,应该使用 swift 提供的一些绑定或者通知框架。

常见的绑定方法当然是 @Binding@State ,当然这个方法仅限于 swiftUI,那么,在 UIKit 中显示了 swiftUI view 的情况下,怎么绑定呢?这里就用到 NotificationCenter。

NotificationCenter

假设我们有一个 Student 类,若其名字被修改,则通知 StudentObserver,按照设计原则,Student 应该是不知道谁在观察它的,因此,Student 需要解藕 StudentObserver,此时就需要 NotificationCenter:

上面的代码可以用下面的图来总结:

主要有以下几点需要注意:

1、访问系统的NotificationCenter 对象是通过访问 default 成员来实现的。

2、addObserver 这个函数需要使用 selector 传入被调函数,即实现 studentObserver.observerStudent(student) 逻辑。 关于 selector 的话题之前谈过。

3、addObserverobject 参数的意思是如果传入 nil,则任何一个对象都应可以 post ,而若传入某个对象,则只有这个传入的对象的 post 调用才有作用。例如,如果上面的例子传入的 s 对象,那么 s1 的 s1.name = "jane"是不会触发 observeStudent 调用的。

4、上面的例子中我们对 Notification.Name 做了一个 extension,注意 extension 只可以增加不再用类对象内存的属性,比如 static 和计算属性。

5、若确定不再观察,及时调用 removeObserver

在 UIKit 中使用 swiftUI 建议是使用 NotificationCenter 来相互交互通信的。

UserDefaults

UserDefaults 也可以做到 UIKit 和 swiftUI 共享数据。但要注意,UserDefaults 其实是一个轻量数据库,也就是会有持久化动作,这不可避免会有:1、持久化数据的问题;2、因为持久化,而且 UserDefaults 定位是数据库,因此效率肯定没有 NotificationCenter 高。正确的做法应该是使用 Notification 观察 UserDefaults :

这里不过多解释,具体用法详看文档。

唯一要说的,是 UserDefaults 既然持久化,那么其持久化文件放在哪?实际上每个苹果 app 都有自己的沙盒环境,其环境路径是 ~/Library/containers/xxxxx/Data,其中 xxxxx 是 app 的名称,在 Data 目录中,是 app 访问的主要目录,其中的 Library/Prereferences 存放了一些 plist 文件。苹果不推荐去直接修改这些文件,应该使用 UserDefaults 的接口来进行操作。

使用 NSHostingView 快速嵌入 cocoa

前面说了,使用NSHostingView 可以快速的吧 swiftUI 嵌套入 cocoa 框架中,这里再介绍一下使用 NSHostingView 快速把一个定制的 swiftUI view 嵌入 table view 中。

首先,下载 SF symbol app,这个工具可以方便浏览苹果提供的标准图标。

例如之前的例子中,我们使用 star 这个图标来标星:

首先创建一个 swiftUI view:

这个是一个很简单 view,现在在 table 显示的时候,直接创建 NSHostingView

上面的代码中,直接用了 NSHostingView 来封装 swfitUI view,相比之前的 NSHostingController ,它没有属性设置面板,可以作为 cocoa 的子 UI 使用。

总结

本节主要是 cocoa 嵌入 swiftUI,主要使用 NSHostingController(作为独立框) 或 NSHostingView (作为子 UI),可以使用 NotificationCenter 来实现 cocoa 和 swfitUI 之间的通信,可以用 UserDefaults 来存储轻变量配置。

实际上,反过来 swiftUI 也可以嵌入 cocoa 框架,是使用 NSViewRepresentable ,但考虑到未来更多是在 cocoa 上开发,swiftUI 作为自定义控件,因此可能暂时用不到。

\ No newline at end of file diff --git a/index.html b/index.html index 3facd2b..ac9addc 100644 --- a/index.html +++ b/index.html @@ -742,6 +742,6 @@ 如卓
-
+

这里是如卓的生活,数学学习和编程分享

社交媒体主页:豆瓣 X(Twitter)

余弦定理证明

π 的推理

使用无穷级数计算一道求极限题

偶函数在x=0处的导数

 

制作一个可以响应down,up事件和大范围点击事件的按钮

解决 Label 对齐时出现漂移的问题

【swift基础】增删查改之显示列表(table view)初始化

【swift基础】增删查改之删(更多核心概念的理解)

【swift基础】增删查改之改(用delegate做出做出更多细节)

【swift基础】增删查改之排序和selector

【swift基础】在 UIKit 中使用 swiftUI

 

\ No newline at end of file diff --git "a/\343\200\220swift\345\237\272\347\241\200\343\200\221\345\234\250UIKit\344\270\255\344\275\277\347\224\250swiftUI.md" "b/\343\200\220swift\345\237\272\347\241\200\343\200\221\345\234\250UIKit\344\270\255\344\275\277\347\224\250swiftUI.md" index 2390d67..766064c 100644 --- "a/\343\200\220swift\345\237\272\347\241\200\343\200\221\345\234\250UIKit\344\270\255\344\275\277\347\224\250swiftUI.md" +++ "b/\343\200\220swift\345\237\272\347\241\200\343\200\221\345\234\250UIKit\344\270\255\344\275\277\347\224\250swiftUI.md" @@ -86,7 +86,7 @@ class SettingsHostingController: NSHostingController { 最后在 property 面板中将控件和类关联起来: -![](https://wecache.com/appledev/swiftuiincocoa-1.png) +![](https://wecache.com/appledev/swiftuiincocoa-2.png) 这样我们就可以在 UIKit 的代码中通过 `SettingsHostingController` 来控制一个用 swiftUI 编写的 `SettingsView` 了。 @@ -94,11 +94,13 @@ class SettingsHostingController: NSHostingController { 显示 hosting controller 其实就是现实其关联的 swiftUI 对象。如果我们打开面板,会发现 hosting controller 有一个 action 消息叫 show 或者 modal,因此只要有人给他发 show 或者 modal 消息就可以显示 hosting controller。 -![](https://wecache.com/appledev/swiftuiincocoa-2.png) +![](https://wecache.com/appledev/swiftuiincocoa-3.png) 这里我们把它绑定到一个 menu 上,只需要 control 拉动即可发送 show 或者 modal 消息: -![](https://wecache.com/appledev/swiftuiincocoa-3.png) +![](https://wecache.com/appledev/swiftuiincocoa-5.png) + +![](https://wecache.com/appledev/swiftuiincocoa-4.png) show 和 modal 的区别就是前者不阻塞父 view 但后者会。 @@ -209,7 +211,7 @@ UserDefaults 也可以做到 UIKit 和 swiftUI 共享数据。但要注意,Use 例如之前的例子中,我们使用 star 这个图标来标星: -![](https://wecache.com/appledev/swiftuiincocoa-4.png) +![](https://wecache.com/appledev/swiftuiincocoa-6.png) 首先创建一个 swiftUI view: diff --git "a/\345\246\202\345\215\223.md" "b/\345\246\202\345\215\223.md" index 6664b74..2fca3b9 100644 --- "a/\345\246\202\345\215\223.md" +++ "b/\345\246\202\345\215\223.md" @@ -27,3 +27,5 @@ [【swift基础】增删查改之改(用delegate做出做出更多细节)](https://wecache.com/appledev/swift-editable.html) [【swift基础】增删查改之排序和selector](https://wecache.com/appledev/bind-datasource.html) + +[【swift基础】在 UIKit 中使用 swiftUI ](https://wecache.com/appledev/swiftuiincocoa.html)