UIKit — SwiftUI 中使用 UIKit
This article is extracted from the chat log with AI. Please identify it with caution.

官方教程 Interfacing with UIKit

在 SwiftUI 项目中集成 UIKit 组件,主要通过 UIViewRepresentableUIViewControllerRepresentable 协议实现。以下是详细步骤和示例:


1. 集成 UIKit 视图(UIView) #

步骤: #

  1. 创建遵循 UIViewRepresentable 的结构体
  2. 实现 makeUIView(context:) 方法,创建并配置 UIKit 视图。
  3. 实现 updateUIView(_:context:) 方法,处理数据更新。
  4. 使用 Coordinator 处理交互和代理方法。

示例:集成 UILabel #

import SwiftUI
import UIKit

struct MyUILabel: UIViewRepresentable {
    var text: String // 数据绑定
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.textColor = .red
        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.text = text // 更新数据
    }
}

// 在 SwiftUI 中使用
struct ContentView: View {
    @State private var labelText = "Hello UIKit!"
    
    var body: some View {
        VStack {
            MyUILabel(text: labelText)
            Button("Change Text") {
                labelText = "Text Updated!"
            }
        }
    }
}

2. 处理交互和代理(如 UITextField #

示例:支持双向绑定的 UITextField #

struct MyTextField: UIViewRepresentable {
    @Binding var text: String
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.borderStyle = .roundedRect
        textField.delegate = context.coordinator // 设置代理
        return textField
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
    }
    
    // 创建 Coordinator 处理代理方法
    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var text: String
        
        init(text: Binding<String>) {
            _text = text
        }
        
        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }
    }
}

// 在 SwiftUI 中使用
struct ContentView: View {
    @State private var inputText = ""
    
    var body: some View {
        VStack {
            MyTextField(text: $inputText)
            Text("You typed: \(inputText)")
        }
    }
}

3. 集成 UIKit 视图控制器(UIViewController) #

示例:集成 UIImagePickerController #

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var selectedImage: UIImage?
    @Environment(\.presentationMode) var presentationMode
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = .photoLibrary
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker
        
        init(parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[.originalImage] as? UIImage {
                parent.selectedImage = image
            }
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

// 在 SwiftUI 中使用
struct ContentView: View {
    @State private var showImagePicker = false
    @State private var selectedImage: UIImage?
    
    var body: some View {
        VStack {
            if let image = selectedImage {
                Image(uiImage: image)
                    .resizable()
                    .scaledToFit()
            }
            Button("Select Image") {
                showImagePicker = true
            }
        }
        .sheet(isPresented: $showImagePicker) {
            ImagePicker(selectedImage: $selectedImage)
        }
    }
}

关键点总结 #

  1. 协议选择

    • 集成 UIViewUIViewRepresentable
    • 集成 UIViewControllerUIViewControllerRepresentable
  2. 数据传递

    • 使用 @Binding 实现 SwiftUI 与 UIKit 的双向数据绑定。
  3. 交互处理

    • 通过 Coordinator 处理 UIKit 的代理方法和事件回调。
  4. 布局适配

    • UIKit 视图的尺寸默认由 SwiftUI 管理,可通过 .frame() 修饰符调整。
  5. 生命周期

    • updateUIViewupdateUIViewController 中响应数据变化。
    • Coordinator 中处理 UIKit 的生命周期事件。

常见问题处理 #

  • 布局冲突:确保 UIKit 视图的 translatesAutoresizingMaskIntoConstraints 设置为 false,或使用 Auto Layout。
  • 手势识别:在 makeUIView 中添加 UIGestureRecognizer,通过 Coordinator 回调到 SwiftUI。

通过上述方法,可以灵活地将 UIKit 组件嵌入 SwiftUI,结合两者的优势构建应用。

本文共 829 字,创建于 Apr 27, 2025
相关标签: Xcode, SwiftUI, UIKit, ByAI