The main purpose of this article is to address the current shortcomings of TextView in SwiftUI. TextView of SwiftUI in Xcode Version 11.1 still has many problems. It is urgent to use text that cannot be displayed correctly inside the view. The current solution is to use UITextView to “save the country with curves”.

Understand the Representable agreement

Representable allows us to render UIView, NSView, and WKInterfaceObject in Swift

The relationship is as follows:

UIView UIViewRepresentable
NSView NSViewRepresentable
WKInterfaceObject WKInterfaceObjectRepresentable

I. The Representable agreement has two methods that must be enforced

  • 1. (Optional) Make Coordinator is invoked first during initialization

  • 2. MakeUIView (must) is where you create the view or controller you want to render in SwiftUI

  • 3. UpdateUIView (mandatory) The method is to update the view to the current configuration

  • 4. (Optional) Call before the dismantling view disappears

Called first during initializationMakeMethod, and then callupdateMethod,updateMethods can be called multiple times, whenever updates are requested, and these are the only two necessary methods to render the view


2. UIViewRepresentableContext

The above two mandatory methods of view presentation are not simple view presentation in real projects, but more action events or delegates, such as:

  1. Read content in SwiftUI and respond to it
  2. Know if there is an animation on the current view
  3. And so on…

To better handle the relationship between view and SwiftUI directly, the Representable protocol is critical; It can be used in views, view controllers, and interface controllers.

Representable ContextThere are three properties:

  • Coordinator is used to implement common patterns that help you coordinate your views and SwiftUI including delegate, data source and target action.

  • 2.Environment helps you read SwiftUI’s Environment, which could be the system Environment, such as color scheme or size category or device orientation. It can also be a custom environment property of the app.

  • 3.Transaction lets our view know if there is animation in SwiftUI, and representable context is available for views, view controllers, and interface controllers.


3. The use of UIViewRepresentableContext

Example: Embed uiKit-based UITextView controls in SwiftUI View

Above we review:


Make Coordinator(optional); Make View; Update View; 4. (Optional); 4. Representable Context 1. Coordinator 2. Environment 3. TransactionCopy the code

We pass the Representable Context parameter in Make and Update views because of three properties of the Representable Context: Coordinator Environment Transaction

If a Coordinator is to be used, it needs to be created in the optional Make Coordinator method. In the initialization process, the first call is the Make Coordinator method. Uikit-related action events or delegates can be processed in Make Coordinator so that uiKit-related action events or delegates can be transferred to SwiftUI.

Let’s look at examples:

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
    }
}
Copy the code
  1. First call makeCoordinator create UIViewRepresentableContext for processing action in UIKit events or entrust;

  2. Add the action event or delegate target textView.delegate = Context.coordinator to the makeUIView

4. The last

How to create using UITextView in SwiftUI has been detailed above, more custom processing needs to be extended according to the requirements; But the core point is the use of two things:

1. UIViewRepresentable

2. UIViewRepresentableContext


SwiftUI use UIKit directly in English