0

I have a multi-line UITextView and sometimes the text wraps several lines. I want to get the text from it with line breaks from what is visible on the iphone screen.

This is useful because I have a UITextView that changes font size with the UI and I want to capture the text as the user sees it on the screen.

Getting the text from the UITextView with textview.text does not contain those. (Although it does contain any line breaks that a user typed by pressing "return" on the keyboard.)

I think maybe you need to measure the height of the UITextView and go through each character but I am not sure how to do that. I also want it to work with emojis.

MaxSped
  • 117
  • 1
  • 1
  • 15
  • TextView.text will show `\n` wherever `return` key is hit, explicit return hits are properly represented if you are talking about text being written to next line because of textview width thats obviously cant be captured. example I type Dddd and hit return 3 times textView.text output is `Optional("Dddd\n\n\n\nMmmm")` – Sandeep Bhandari Jan 21 '21 at 07:29

4 Answers4

0

It seems that you want to get a snapshot of UITextView instead of get textview.text, so what you need is to learn how to draw UITextView's content as a picture.

For how to drawing a snapshot of UIView, try this.

For how to drawing a snapshot of NSAttribeString, try draw(with:options:context:).

Owen Zhao
  • 3,205
  • 1
  • 26
  • 43
0

Core Text or TextKit are the best options to work with text.

This answer shows how to get word-wrapped lines using Core Text: https://stackoverflow.com/a/13588322/1837959.

Or you could access the layoutManager (NSLayoutManager) of the UITextView to access the layout data.

storoj
  • 1,851
  • 2
  • 18
  • 25
0

Sounds like a hacky solution but kinda not really:

Use the Vision Framework's text recognition to convert an image to text.

  1. convert the view to image
extension UIView {
    var toImage: UIImage?  {
        let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
        return renderer.image { (context) in
            self.layer.render(in: context.cgContext)
        }
    }
}
let yourTextView = UITextView()
let img = yourTextView.toImage()
  1. Follow article
guard let cgimg = img.cgImage else {return}

// Create a new image-request handler.
let requestHandler = VNImageRequestHandler(cgImage: cgImage)

// Create a new request to recognize text.
let request = VNRecognizeTextRequest(completion: recognizeTextHandler)

do {
    // Perform the text-recognition request.
    try requestHandler.perform([request])
} catch {
    print("Unable to perform the requests: \(error).")
}
// Process the Results
func recognizeTextHandler(request: VNRequest, error: Error?) {
    guard let observations =
            request.results as? [VNRecognizedTextObservation] else {
        return
    }
    let recognizedStrings = observations.compactMap { observation in
        // Return the string of the top VNRecognizedText instance.
        return observation.topCandidates(1).first?.string
    }
    
    // Use the result
    processResults(recognizedStrings)
}
shayegh
  • 302
  • 1
  • 9
0

UITextView Text will show '\n' for user input(when he press enter). If User does not press enter/return and keep writing the word wrap will happen according to size/width of UITextView. So you should not anything. So if you see "\n" just change it to
, if you are displaying it in Website or using Web Views html layout. Or Just replace all "\n" with space and Don't wrap it let width of the view decide how to wrap it. Capturing the Screen of IOS iPhone and showing it in same way looks more weird.

For Example.

Think this is

Data even

there is no

return. It should be in one line.

Jin Thakur
  • 2,711
  • 18
  • 15