iOS 13 UITextView 转换为图像不正常,在 iOS 12 及以下版本正常工作。

8
如何解决iOS 13中的此问题? 我正在截取UITextView内容大小的屏幕截图。在iOS 12之前,一切都正常。但是从iOS 13开始出现问题,它没有完整地截取屏幕截图。下面是小于iOS 12和iOS 13及以后的输出图片。 小于iOS 12

iOS 13

以下是我用于截取UITextView屏幕截图的代码:
let textView = UITextView()
UIGraphicsBeginImageContextWithOptions(textView.contentSize, textView.isOpaque, 0.0)
let savedContentOffset: CGPoint = textView.contentOffset
let savedFrame: CGRect = textView.frame
textView.frame = CGRect(x: 0, y: 0, width: textView.contentSize.width, height: textView.contentSize.height)
textView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
textView.contentOffset = savedContentOffset
textView.frame = savedFrame
UIGraphicsEndImageContext()

我已经解决了这个问题。下面是更新后的可用代码

选项1:- 以下代码使用UILabel

let SCREEN_WIDTH = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
func buttonAction() {
    let textView = UITextView()
    textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)
    let lab = UILabel(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH - 20, height: textView.contentSize.height))
    lab.backgroundColor = UIColor.white
    lab.font = textView.font
    lab.textColor = UIColor.black
    lab.numberOfLines = 0
    lab.text = textView.text
    textView.addSubview(lab)

    UIGraphicsBeginImageContextWithOptions(CGSize(width: SCREEN_WIDTH - 20, height: textView.contentSize.height), _: true, _: 1)
    if let context = UIGraphicsGetCurrentContext() {
        lab.layer.render(in: context)
    }
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)
    lab.removeFromSuperview()

}

选项2:- 以下代码使用TempView

let SCREEN_WIDTH = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT = UIScreen.main.bounds.size.height

func buttonAction() {
   let textView = UITextView()
   textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)
UIGraphicsBeginImageContextWithOptions(CGSize(width: SCREEN_WIDTH - 20, height: textView.contentSize.height), _: true, _: 1)
if #available(iOS 13, *) {
    // iOS 13 (or newer)
    let tempView = UIView(frame: CGRect(x: 0, y: 0, width: textView.contentSize.width, height: textView.contentSize.height))
    tempView.addSubview(textView)
    if let context = UIGraphicsGetCurrentContext() {
        tempView.layer.render(in: context)
    }
    tempView.removeFromSuperview()
    view.addSubview(textView)
} else {
    // iOS 12 or older
    if let context = UIGraphicsGetCurrentContext() {
        textView.layer.render(in: context)
    }
}

选项3:
尝试使用第三方库,我使用过YYTextView。https://github.com/ibireme/YYText


你尝试过新的 UIGraphicsImageRenderer 吗?在 Swift iOS 中截屏? - Cœur
5个回答

2
不要绘制图层,而是使用attributedText。
let size = self.textView.contentSize
UIGraphicsBeginImageContextWithOptions(size, self.textView.isOpaque, 0)
//the textView has 8 margin
textView.attributedText.draw(in: CGRect.init(x: 0, y: 0, width: size.width - 16, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

谢谢回复。实际上我想在图层上绘制,因为我还要在那个文本视图中添加图片。 - Aslam
使用NSTextAttachment添加图片,attributedText也可以正确绘制。 - Code Farmer
是的,我同意。但我们的要求不同... 图像可以拖动、调整大小、旋转、扩展... 这些功能无法使用NSTextAttachment实现。 - Aslam

0

看起来我的问题是与图层有关,设置图层的内容大小有效。在上下文中呈现之前,使用所需大小设置图层框架属性,这将在图像中绘制完整的内容。希望能有所帮助。


0
为了使它正常工作,我不得不在渲染时使用UILabel。
它与textview具有相同的约束/字体/文本配置,当渲染时,在标签中设置文本,隐藏textview并显示标签,反之亦然。也许对于我来说有点复杂,因为我要渲染的视图不在屏幕上,但仍可能是一个选择。

谢谢您的回复。使用UILabel可以工作。但是我必须只使用TextView,因为需要多个图像。这些图像可以拖动、调整大小、扩展,然后需要截屏。我认为使用UILabel无法满足我们的要求。您能否提供其他解决方案? - Aslam

0

尝试使用UIlabel或TempView或第三方库

以下是可行的代码:

选项1:使用UILabel的下面的代码

let SCREEN_WIDTH = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
func buttonAction() {
    let textView = UITextView()
    textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)

    let lab = UILabel(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH - 20, height: textView.contentSize.height))
    lab.backgroundColor = UIColor.white
    lab.font = textView.font
    lab.textColor = UIColor.black
    lab.numberOfLines = 0
    lab.text = textView.text
    textView.addSubview(lab)

    UIGraphicsBeginImageContextWithOptions(CGSize(width: SCREEN_WIDTH - 20, height: textView.contentSize.height), _: true, _: 1)
    if let context = UIGraphicsGetCurrentContext() {
        lab.layer.render(in: context)
    }
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)
    lab.removeFromSuperview()

}

选项2:- 以下代码使用TempView

let SCREEN_WIDTH = UIScreen.main.bounds.size.width
let SCREEN_HEIGHT = UIScreen.main.bounds.size.height

func buttonAction() {
   let textView = UITextView()
   textView.frame = CGRect(x: 10, y: 50, width: SCREEN_WIDTH - 20, height: SCREEN_HEIGHT * 2)
   UIGraphicsBeginImageContextWithOptions(CGSize(width: SCREEN_WIDTH - 20, height: textView.contentSize.height), _: true, _: 1)

   if #available(iOS 13, *) {
    // iOS 13 (or newer)
    let tempView = UIView(frame: CGRect(x: 0, y: 0, width: textView.contentSize.width, height: textView.contentSize.height))
    tempView.addSubview(textView)
    if let context = UIGraphicsGetCurrentContext() {
        tempView.layer.render(in: context)
    }
    tempView.removeFromSuperview()
    view.addSubview(textView)
 } else {
    // iOS 12 or older
    if let context = UIGraphicsGetCurrentContext() {
        textView.layer.render(in: context)
    }
}

选项3:尝试使用我使用过的YYTextView第三方库 https://github.com/ibireme/YYText


0

以下方法对我有用

extension UITextView {
/**
 Convert TextView to UIImage
 */
 func toImage() -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0)
    defer { UIGraphicsEndImageContext() }
    if let context = UIGraphicsGetCurrentContext() {
        self.layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image
    }
    return nil
  }
}

使用:

UIImageWriteToSavedPhotosAlbum(self.textView.toImage()!,self, nil, nil)

感谢回复。是的,在iOS 13中它不起作用。在iOS 12以下表现良好。 - Aslam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接