Search code examples
swiftuiuitextviewios16textkit

SiwiftUI: UITextView is switching to TextKit 1


I got the log message UITextView is switching to TextKit 1 compatibility mode because its textStorage contains attributes which are not compatible with TextKit 2 by using documentType: NSAttributedString.DocumentType.html for a NSAttributedString.

Example:

func makeUIView(context: Context) -> UITextView {
    let textView = UITextView()
    return textView
}

func updateUIView(_ uiView: UITextView, context _: Context) {
    var currentText: NSAttributedString?
    let htmlString = "<html><body><h1>Example</h1></body></html>"
    
    guard let encodedData = htmlString.data(using: .utf8) else {
        fatalError("Could not encode HTML data")
    }
    
    do {
        currentText = try NSAttributedString(data: encodedData,
                                             options: [
                                                .documentType: NSAttributedString.DocumentType.html,
                                                .characterEncoding: String.Encoding.utf8.rawValue
                                             ],
                                             documentAttributes: nil)
    } catch let error as NSError {
        fatalError(error.localizedDescription)
    } catch {
        fatalError("error")
    }
    
    uiView.attributedText = currentText
}

Is there any idea how to fix it?


Solution

  • You can choose TextKit 1 or TextKit 2.

    In iOS 16+, by default UITextView uses TextKit 2. If you want to use TextKit 1, construct the UITextView using this constructor:

    init(usingTextLayoutManager: Bool)
    

    Creates a new text view, with or without a text layout manager depending on the Boolean value you specify.

    https://developer.apple.com/documentation/uikit/uitextview

    If usingTextLayoutManager is true, UITextView uses TextKit 2. If it is false, TextKit 1 will be used.

    TextKit 2

    let textView = UITextView(usingTextLayoutManager: true)
    

    TextKit 1

    let textView = UITextView(usingTextLayoutManager: false)
    

    It is the same in NSTextView also.