# SwiftUI 使用 UIKit 做爲UI控件不足的補充

本文主要目的就是解決目前 SwiftUITextView 的不足. SwiftUIXcode Version 11.1 中的 TextView 依然有許多問題, 文本在視圖內部沒法正確顯示是使用的當務之急,目前的解決辦法是利用 UITextView進行 「 曲線救國 」bash

先了解Representable 協議

Representable 協議容許咱們在 Swift 中呈現 UIView, NSView, WKInterfaceObjectapp

其關係對應以下:ide

UIView UIViewRepresentable
NSView NSViewRepresentable
WKInterfaceObject WKInterfaceObjectRepresentable

一. Representable 協議有兩個必須執行的方法

  • 1. Make Coordinator(可選) 初始化過程當中首先調用動畫

  • 2. makeUIView(必須) 是建立你但願在SwiftUI中呈現的視圖或者控制器的地方ui

  • 3. updateUIView(必須) 該方法是把這個視圖,更新到當前配置的地方spa

  • 4. Dismantle(可選) 視圖消失以前調用code

在初始化過程當中首先調用 Make 方法,而後再調用 update方法, update方法能夠屢次調用,只要是請求更新的時候均可以調用, 這兩個方法是呈現視圖僅有的兩個必須方法教程


二. UIViewRepresentableContext

上面說的兩個視圖呈現的必須方法,在實際的項目中使用不多是簡單的視圖展現,更多的是動做事件或者委託,好比:接口

  1. 在SwiftUI 中讀取內容,並做出響應
  2. 瞭解當前視圖上是否有動畫
  3. 等等...

爲了更好的處理視圖SwiftUI直接的關係,Representable協議是關鍵的存在;它能夠在視圖、視圖控制器、以及界面控制器中使用。事件

Representable Context 有三個屬性:

  • 1.Coordinator 用於實現常見模式,幫助你協調你的視圖和 SwiftUI 包括委派,數據源和目標動做.

  • 2.Environment 幫助你讀取SwiftUI的環境, 這多是系統環境,例如配色方案或尺寸類別或設備方向. 也能夠是應用app自定義的環境屬性.

  • 3.Transaction 讓咱們的視圖知道SwiftUI中是否有動畫, 可表示的上下文可用於視圖,視圖控制器以及接口控制器.


三. UIViewRepresentableContext 的使用

案例:在 SwiftUI 視圖中嵌入基於 UIKitUITextView的控件

上面咱們回顧:


一.Representable 協議有兩個必須執行的方法

1. Make Coordinator(可選)
2. Make View
3. Update View
4. Dismantle View(可選)

二. Representable Context

1. Coordinator
2. Environment
3. Transaction
	
複製代碼

Make ViewUpdate View 中咱們傳入 Representable Context參數,因爲 Representable Context 的三個屬性: Coordinator Environment Transaction

若是要使用 Coordinator,則須要在可選的 Make Coordinator 方法中建立,在初始化過程當中首先調用的是 Make Coordinator方法, 咱們把 UIKit相關的動做事件或者委託在 Make Coordinator中處理好,這樣關於 UIKit 相關的 動做事件或者委託的就能夠傳遞到 SwiftUI 裏面了;

咱們看例子:

struct TextView: UIViewRepresentable {
    
    class Coordinator : NSObject, UITextViewDelegate {
        var textView: TextView

        init(_ uiTextView: TextView) {
            self.textView = uiTextView
        }

        func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
            return true
        }

        func textViewDidChange(_ textView: UITextView) {
            self.textView.text = textView.text
        }
    }
    
    @Binding var text: String

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

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator
        textView.isScrollEnabled = true
        textView.isEditable = true
        textView.isUserInteractionEnabled = true
        return textView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
    }
}
複製代碼
  1. 先調用 makeCoordinator 建立 UIViewRepresentableContext用於處理 UIKit 中的動做事件或者委託;

  2. makeUIView 中添加動做事件或者委託的目標 textView.delegate = context.coordinator

四. 最後

關於如何在SwiftUI中打造使用 UITextView上面已經很詳細,更多的自定義處理須要根據需求進一個擴展;可是核心點就是兩點的使用:

1. UIViewRepresentable

2. UIViewRepresentableContext


本文在蘋果開發者官網教程中有 SwiftUI 直接使用 UIKit 英文教程

相關文章
相關標籤/搜索