Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 在 SwiftUI 中使用 UIKit 组件

在 SwiftUI 中使用 UIKit 组件

SwiftUI 提供了一种声明式的方法来构建用户界面,但在某些情况下,你可能需要使用 UIKit 组件。SwiftUI 可以与 UIKit 无缝集成,让你在 SwiftUI 界面中使用 UIKit 的视图和控制器。以下是如何在 SwiftUI 中使用 UIKit 组件的指南和示例。

1. 使用 UIViewRepresentable

要在 SwiftUI 中使用 UIKit 视图,必须创建一个遵循 UIViewRepresentable 协议的结构体。这个协议允许你包装 UIKit 视图并将其嵌入到 SwiftUI 视图中。

示例:使用 UILabel

以下是一个使用 UILabel 的示例:

import SwiftUI

struct LabelView: UIViewRepresentable {
    var text: String

    // 创建 UILabel 实例
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.textAlignment = .center
        return label
    }

    // 更新 UILabel 的内容
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.text = text
    }
}

struct ContentView: View {
    var body: some View {
        LabelView(text: "Hello, UIKit in SwiftUI!")
            .padding()
            .font(.title)
    }
}

2. 使用 UIViewControllerRepresentable

类似于 UIViewRepresentable,你可以使用 UIViewControllerRepresentable 来包装 UIKit 控制器。

示例:使用 UIImagePickerController

以下是一个使用 UIImagePickerController 的示例:

import SwiftUI
import UIKit

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    var sourceType: UIImagePickerController.SourceType

    // 创建 UIImagePickerController 实例
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = sourceType
        return picker
    }

    // 更新 UIImagePickerController
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}

    // 创建 Coordinator 用于处理 UIImagePickerController 的代理
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        var parent: ImagePicker

        init(_ parent: ImagePicker) {
            self.parent = parent
        }

        // 处理选择的图像
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.image = uiImage
            }
            picker.dismiss(animated: true)
        }

        // 处理取消操作
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            picker.dismiss(animated: true)
        }
    }
}

struct ContentView: View {
    @State private var image: UIImage?
    @State private var showingImagePicker = false

    var body: some View {
        VStack {
            Button("Select Image") {
                showingImagePicker = true
            }
            .sheet(isPresented: $showingImagePicker) {
                ImagePicker(image: $image, sourceType: .photoLibrary)
            }

            if let selectedImage = image {
                Image(uiImage: selectedImage)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 200, height: 200)
            }
        }
    }
}

3. 使用 UIKit 控件

除了创建自定义包装器外,还可以直接在 SwiftUI 中使用 UIKit 控件,特别是那些支持 UIViewController 的组件。

示例:使用 UISlider

import SwiftUI

struct SliderView: UIViewRepresentable {
    @Binding var value: Float

    func makeUIView(context: Context) -> UISlider {
        let slider = UISlider()
        slider.addTarget(context.coordinator, action: #selector(Coordinator.valueChanged(_:)), for: .valueChanged)
        return slider
    }

    func updateUIView(_ uiView: UISlider, context: Context) {
        uiView.value = value
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject {
        var parent: SliderView

        init(_ parent: SliderView) {
            self.parent = parent
        }

        @objc func valueChanged(_ sender: UISlider) {
            parent.value = sender.value // 更新绑定的值
        }
    }
}

struct ContentView: View {
    @State private var sliderValue: Float = 0.5

    var body: some View {
        VStack {
            SliderView(value: $sliderValue)
                .padding()
            Text("Slider Value: \(sliderValue)")
        }
    }
}

4. 总结

  • UIViewRepresentable:用于包装 UIKit 视图,以便在 SwiftUI 中使用。
  • UIViewControllerRepresentable:用于包装 UIKit 控制器,适合更复杂的视图。
  • Coordinator:通过 Coordinator 处理 UIKit 组件的事件和数据。
  • 直接使用 UIKit 控件:在 SwiftUI 中使用 UIKit 组件,提供更多灵活性。

通过这些方法,你可以在 SwiftUI 应用中灵活地使用 UIKit 组件,充分发挥两者的优势。

Last Updated:: 11/5/24, 3:24 PM