iOS 13 UITextView 将 UITextView 转换为图像无法正常工作。在 iOS 12 以下正常工作

Posted

技术标签:

【中文标题】iOS 13 UITextView 将 UITextView 转换为图像无法正常工作。在 iOS 12 以下正常工作【英文标题】:iOS 13 UITextView converting UITextView to image is not working properly. Working fine in below iOS 12 【发布时间】:2019-10-16 02:57:25 【问题描述】:

如何在 ios 13 中解决这个问题? 我正在截取 UITextView 内容大小的屏幕截图。直到 iOS 12 一切正常。但是从 iOS 13 开始出现问题,它没有截取它正在剪切的完整屏幕截图。下面是低于 iOS 12 和 iOS 13 之后的输出图片。 Less than iOS 12

下面是我用来截取 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 吗? Screenshot in Swift iOS? 【参考方案1】:

不画图层,改用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()

【讨论】:

感谢您的回复。实际上我想在 layer.bcoz 上绘图,我还必须在该 textview 中添加图像.. 使用NSTextAttachment添加图片,attributeText也能正确绘制 是的,我同意。但我们的要求是不同的。图像可以拖动、调整大小、旋转、展开......所有这些我都不能使用 NSTextAttachment 来做......【参考方案2】:

以下对我有用

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)

【讨论】:

感谢您的回复..是的,它在 iOS13 中不工作..它在低于 iOS12 的情况下工作正常【参考方案3】:

似乎问题出在我为图层设置内容大小的图层上。在上下文渲染之前,将 layer frame 属性设置为所需的大小,这将在图像中绘制完整的内容。希望这会有所帮助

【讨论】:

【参考方案4】:

为了让它工作,我必须在渲染时使用 UILabel。

它配置了与文本视图相同的约束/字体/文本,并且在渲染时 - 在标签中设置文本,隐藏文本视图并显示标签,反之亦然。对我来说可能稍微不那么复杂,因为我正在渲染的视图不在屏幕上,但可能仍然是一个选项。

【讨论】:

谢谢你的回复..使用 uilabel 它的工作..但我必须使用 TextView 只是因为需要多个图像。图像可以拖动,调整大小,然后需要截图..我想使用 UILabel 无法达到我们的要求..您能否为此提出任何其他解决方案【参考方案5】:

尝试使用 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

【讨论】:

以上是关于iOS 13 UITextView 将 UITextView 转换为图像无法正常工作。在 iOS 12 以下正常工作的主要内容,如果未能解决你的问题,请参考以下文章

IOS textView 委托

UITextView insertText 调用 shouldChangeTextInRange: replacementText:

使用不可见的 UILabel 并触发 UITextView 事件或不使用 UILabel 并处理 UITextView 点击识别器

在启用滚动的堆栈视图中扩展 UITextView

调整表格视图单元格以显示 UITextView 和 UIWebView

使用自动布局问题在 UIScrollView 中调整 UITextView 的大小