0
votes

I have a UITextView that takes up an entire scene (view). The textviews length varies depending on how much content there is. It could be very long and therefore does not all appear on the screen -- you have to scroll to see the rest. Also, the content could have images inside it using NSTextAttachment. My goal is to create an image of the entire textview. It should even include content that is offscreen (not currently visible). Here is what I have so far:

func textViewImage() -> UIImage {

    UIGraphicsBeginImageContext(textView.contentSize)

    let savedContentOffset: CGPoint = textView.contentOffset
    let savedFrame: CGRect = textView.frame

    textView.contentOffset = CGPointZero
    textView.frame = CGRectMake(0, 0, textView.contentSize.width, textView.contentSize.height)

    textView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()

    textView.contentOffset = savedContentOffset
    textView.frame = savedFrame

    UIGraphicsEndImageContext()

    return image
}

This does not work. It only takes a picture of what is currently visible on the screen. I check to see if this code is working or not working by trying to share it by text message or mail:

 @IBAction func share(sender: UIBarButtonItem) {

    let shareTextViewImage = textViewImage()
    let activityController = UIActivityViewController(activityItems: [shareTextViewImage], applicationActivities: nil)

    self.presentViewController(activityController, animated: true, completion: nil)

}

I got as far as I did thanks to this post on SO and others Getting a screenshot of a UIScrollView, including offscreen parts.

Look forward to some help! Thanks!

Update 1: I created this variable var pageSize: CGSize = CGSizeMake(320, 800) and tried adding it like so: UIGraphicsBeginImageContext(pageSize). This does not work either since it only takes the current screen shot. Anyways this is a fixed size which wouldn't work in the long run since the content size could change --- just wanted to see how this would work out.

Still searching for answers...

1
Instead of rendering the text view, why not just draw the text view's text into the graphics context. You just need the text and the proper frame for it (which you have). - rmaddy
@rmaddy Could you show me how to do this in code? Sorry Im a new to this and don't understand how this code works well. - JEL
@rmaddy I attempted what you mentioned and updated my question. It did not work. I'm not even sure if I did exactly as you said to do. Am I on the right track? - JEL

1 Answers

3
votes

I figured it out myself. This works for me:

    func textViewImage() -> UIImage {

    var image: UIImage? = nil

    UIGraphicsBeginImageContextWithOptions(textView.contentSize, textView.opaque, 0.0)

    let savedContentOffset: CGPoint = textView.contentOffset
    let savedFrame: CGRect = textView.frame

    textView.contentOffset = CGPointZero
    textView.frame = CGRectMake(0, 0, textView.contentSize.width, textView.contentSize.height)

    textView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    image = UIGraphicsGetImageFromCurrentImageContext()

    textView.contentOffset = savedContentOffset
    textView.frame = savedFrame

    UIGraphicsEndImageContext()

    return image!
}

And if you want to share this image:

    @IBAction func share(sender: UIBarButtonItem) {

    let img = textViewImage()
    let shareItem = [img]

    let activityController = UIActivityViewController(activityItems: shareItem, applicationActivities: nil)
    self.presentViewController(activityController, animated: true, completion: nil)

}