Swift Academy · 课时

UIViewRepresentable:封装 UIKit 视图

在 SwiftUI 中实现 makeUIView、updateUIView,并拆除 UIKit 视图。

第 1 / 4 课13 个步骤

UIViewRepresentable:封装 UIKit 视图 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

为什么使用 UIViewRepresentable?

许多 UIKit 视图目前还没有对应的 SwiftUI 实现。UIViewRepresentable 可以将 UIKit 视图桥接到 SwiftUI 中。

import SwiftUI
import UIKit

struct WebView: UIViewRepresentable {
  let url: URL
  // ...
}

必需的方法

实现 makeUIView 来创建视图,并实现 updateUIView 来同步 SwiftUI 的状态变化。

func makeUIView(context: Context) -> WKWebView {
  WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
  uiView.load(URLRequest(url: url))
}

完整的 WebView 示例

这是一个完整的 UIViewRepresentable 示例,它封装了 WKWebView,用于在 SwiftUI 中显示网页内容。

struct WebView: UIViewRepresentable {
  let url: URL
  func makeUIView(context: Context) -> WKWebView { WKWebView() }
  func updateUIView(_ uiView: WKWebView, context: Context) {
    uiView.load(URLRequest(url: url))
  }
}

在 SwiftUI 中使用

像使用任何 SwiftUI 视图一样使用封装后的视图,并正常应用修饰器。

WebView(url: URL(string: "https://apple.com")!)
  .frame(height: 400)
  .cornerRadius(12)

传入数据

通过表示器中存储的属性将数据从 SwiftUI 传递到 UIKit,并在 updateUIView 中更新这些属性。

struct MapView: UIViewRepresentable {
  var region: MKCoordinateRegion
  func makeUIView(context: Context) -> MKMapView { MKMapView() }
  func updateUIView(_ uiView: MKMapView, context: Context) {
    uiView.setRegion(region, animated: true)
  }
}

拆除 UIKit 视图

实现可选的 dismantleUIView,以便在移除视图时清理观察者等资源。

static func dismantleUIView(_ uiView: WKWebView, coordinator: Coordinator) {
  uiView.stopLoading()
}

Context 参数

context 提供对协调器、环境和动画事务的访问。

func updateUIView(_ uiView: MKMapView, context: Context) {
  print(context.environment.colorScheme)  // .light or .dark
}

UIViewRepresentable 中的环境值

从 context.environment 读取 SwiftUI 环境值,以调整 UIKit 配置。

if context.environment.colorScheme == .dark {
  uiView.overrideUserInterfaceStyle = .dark
}

调整 UIKit 视图大小

UIViewRepresentable 使用固有内容大小或 SwiftUI 的 frame 修饰器。实现 sizeThatFits 可进行自定义大小调整。

func sizeThatFits(_ proposal: ProposedViewSize, uiView: WKWebView, context: Context) -> CGSize? {
  CGSize(width: proposal.width ?? 300, height: 400)
}

避免在 makeUIView 中产生副作用

请让 makeUIView 保持纯粹——只负责创建和配置。将由状态驱动的更新放入 updateUIView。

// WRONG:
func makeUIView(context: Context) -> MKMapView {
  let v = MKMapView()
  v.setRegion(region, animated: false)  // belongs in updateUIView
  return v
}

常见的封装视图

使用 UIViewRepresentable 封装的典型 UIKit 视图包括:WKWebView、MKMapView、UITextView、UIImagePickerController 和 AVPlayerLayer。

// UITextView with custom toolbar
struct RichTextEditor: UIViewRepresentable {
  @Binding var text: String
  // makeUIView, updateUIView, Coordinator...
}

快速检查

在初始创建完成后,UIViewRepresentable 会调用哪个方法,将 SwiftUI 状态同步到 UIKit 视图中?

课程回顾

UIViewRepresentable 要求实现 makeUIView(创建一次)和 updateUIView(状态变化时同步)。使用 context.environment 调整外观。在 dismantleUIView 中进行清理。应用 SwiftUI 的 frame 修饰器来控制大小。

免费开始

用 AI 导师学习 Swift — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
122
课程
409

常见问题解答

「UIViewRepresentable:封装 UIKit 视图」课时是免费的吗?

是的 — 「UIViewRepresentable:封装 UIKit 视图」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「UIViewRepresentable:封装 UIKit 视图」这节课中我会学到什么?

在 SwiftUI 中实现 makeUIView、updateUIView,并拆除 UIKit 视图。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「UIViewRepresentable:封装 UIKit 视图」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. UIViewRepresentable:封装 UIKit 视图
  2. 用于代理通信的协调器模式
  3. UIViewControllerRepresentable
  4. UIHostingController:在 UIKit 中使用 SwiftUI
← 返回 Swift Academy