1. UIViewRepresentable UIKit ライブラリの UIView を SwiftUI の View および TextFieldView に変換
1.1 変換された UIView インスタンス UIViewRepresentableBootcamp.swift を作成する
import SwiftUI
/// 呈现/表示视图,视图的转换
/// Convert a UIView from UIKit to SwiftUI
/// UIKit 库中的 UIView 转换为 SwiftUI 中 View
struct UIViewRepresentableBootcamp: View {
@State private var text:String = ""
var body: some View {
VStack {
/// UIView 转换 View
// viewRepresentable
/// 文本输入框 UIkit view 与 SwiftUI 交互
textFieldViewRepresentable
}
}
/// 文本输入框 UIkit 与 SwiftUI 交互
var textFieldViewRepresentable: some View{
VStack {
Text(text)
HStack {
Text("SwiftUI: ")
TextField("Type here...", text: $text)
.padding(.horizontal, 5)
.frame(height: 55)
.background(Color.gray.opacity(0.3).cornerRadius(10))
.padding(.trailing, 10)
}
HStack {
Text("UIKit: ")
UITextFieldViewRepresentable(text: $text)
.updatePlaceholder("New placeholder...")
.padding(.horizontal, 5)
.frame(height: 55)
.background(Color.gray.opacity(0.3).cornerRadius(10))
.padding(.trailing, 10)
}
}
}
/// UIView 转换 View
var viewRepresentable: some View{
VStack {
Text("Hello, world!")
BasicUIViewRepresentable()
}
}
}
/// UITextField
struct UITextFieldViewRepresentable: UIViewRepresentable{
@Binding var text: String
var placeholder: String
let placeholderColor: UIColor
init(text: Binding<String>, placeholder: String = "Default placeholder...", placeholderColor: UIColor = .red) {
self._text = text
self.placeholder = placeholder
self.placeholderColor = placeholderColor
}
func makeUIView(context: Context) -> UITextField {
let textField = getTextField()
textField.delegate = context.coordinator
return textField
}
/// for SwiftUi to UIKit
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = text
}
/// 获取文本输入框
private func getTextField() -> UITextField{
let textField = UITextField(frame: .zero)
let placeholder = NSAttributedString(
string: placeholder,
attributes: [
.foregroundColor : placeholderColor
])
textField.attributedPlaceholder = placeholder
// textField.delegate = self
return textField
}
/// 更新提示文本
func updatePlaceholder(_ text: String) -> UITextFieldViewRepresentable{
var viewRepresentable = self
viewRepresentable.placeholder = text
return viewRepresentable
}
/// 制作协调器
func makeCoordinator() -> Coordinator {
return Coordinator(text: $text)
}
/// 输入文本代理器
class Coordinator: NSObject, UITextFieldDelegate {
@Binding var text: String
init(text: Binding<String>) {
self._text = text
}
func textFieldDidChangeSelection(_ textField: UITextField) {
text = textField.text ?? ""
}
}
}
/// UIView 转换 View
struct BasicUIViewRepresentable: UIViewRepresentable{
func makeUIView(context: Context) -> some UIView {
let view = UIView()
view.backgroundColor = UIColor.red
return view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
struct UIViewRepresentableBootcamp_Previews: PreviewProvider {
static var previews: some View {
UIViewRepresentableBootcamp()
}
}
1.2 レンダリング:
2. UIViewControllerRepresentable/UIKit ライブラリの UIViewController を SwiftUI の View に変換し、UIKit ライブラリのピクチャ セレクター コントローラーを取得します。
2.1 変換された UIViewController インスタンス UIViewControllerRepresentableBootcamp.swift を作成する
import SwiftUI
/// 可转换的视图控制器
struct UIViewControllerRepresentableBootcamp: View {
@State private var showScreen: Bool = false
@State private var image: UIImage? = nil
var body: some View {
VStack {
Text("hi")
if let image = image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 260, height: 260)
}
Button {
showScreen.toggle()
} label: {
Text("Click Here")
}
}
.sheet(isPresented: $showScreen) {
BasicUIViewControllerRepresentable(labelText: "New text here")
//UIImagePickerControllerRepresentable(image: $image, showScreen: $showScreen)
}
}
}
struct UIViewControllerRepresentableBootcamp_Previews: PreviewProvider {
static var previews: some View {
UIViewControllerRepresentableBootcamp()
}
}
/// 图像选择控制器
struct UIImagePickerControllerRepresentable: UIViewControllerRepresentable{
@Binding var image: UIImage?
@Binding var showScreen: Bool
func makeUIViewController(context: Context) -> some UIViewController {
let vc = UIImagePickerController()
vc.allowsEditing = false
vc.delegate = context.coordinator
return vc
}
// from SwiftUI to UIKit
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
// from UIKit to SwiftUI
func makeCoordinator() -> Coordinator {
return Coordinator(image: $image, showScreen: $showScreen)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate,UINavigationControllerDelegate{
@Binding var image: UIImage?
@Binding var showScreen: Bool
init(image: Binding<UIImage?>, showScreen: Binding<Bool>) {
self._image = image
self._showScreen = showScreen
}
// 选中图片
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// 获取字典中的原始图像
guard let newImage = info[.originalImage] as? UIImage else{
return
}
image = newImage
showScreen = false
}
}
}
/// 视图控制器
struct BasicUIViewControllerRepresentable: UIViewControllerRepresentable{
let labelText: String
func makeUIViewController(context: Context) -> some UIViewController {
let vc = MyFirstViewController()
vc.labelText = labelText
return vc
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
}
/// 创建 VIewController
class MyFirstViewController: UIViewController{
var labelText: String = "Starting value"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
let label = UILabel()
label.text = labelText
label.textColor = UIColor.white
view.addSubview(label)
label.frame = view.frame
}
}
2.2 レンダリング: