【问题标题】:UIGraphicsGetImageFromCurrentImageContext() returning blank image in UITableViewCellUIGraphicsGetImageFromCurrentImageContext() 在 UITableViewCell 中返回空白图像
【发布时间】:2017-05-21 07:03:32
【问题描述】:

我已经成功地使用下面的函数来拍摄 UIViews 的快照,但是,现在我在 UITableViewCell 中使用它,它不再起作用了。

static func pictureTaker(_ rawView: UIView) -> UIImageView {
        UIGraphicsBeginImageContextWithOptions(rawView.bounds.size, false, 0)
        rawView.drawHierarchy(in: rawView.bounds, afterScreenUpdates: true)
        let screenshot = UIGraphicsGetImageFromCurrentImageContext();
        let viewImage = UIImageView(image: screenshot)
        UIGraphicsEndImageContext();
        viewImage.frame = rawView.frame
        return viewImage
    }

这是我用来填充 UITableViewCell 的函数的精简版本。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = gamesHolder.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath) as! StandardGameCell
        let row = indexPath.row

        let boardPreviewTemplate = UIView(frame: CGRect(x: 0, y: 0, width: cell.previewBoard.frame.width, height: cell.previewBoard.frame.height))
        GameManagement.setupBoard(boardPreviewTemplate, boardItems: gamesArray[row].board)

        let gamePicture = PageManagement.pictureTaker(boardPreviewTemplate)
        gamePicture.frame = CGRect(x: 0, y: 0, width: gamePicture.frame.width, height: gamePicture.frame.height)

        //Removing preview board items and replacing with picture
        cell.previewBoard.subviews.forEach({ $0.removeFromSuperview() })
        cell.previewBoard.addSubview(gamePicture)

        return cell
    }

在上面的tableView 函数中,我正在以编程方式创建一个新视图来复制cell.previewBoard,但我也尝试直接对cell.previewBoard 进行快照,但这也不起作用。我认为这个问题与 UITableViewCell 加载的时间有关。

我也 100% 肯定该函数正在返回一个图像(但是是一个空白图像),并且它就是我想要的位置。如果我将UIGraphicsBeginImageContextWithOptions(rawView.bounds.size, false, 0) 更改为UIGraphicsBeginImageContextWithOptions(rawView.bounds.size, true, 0),返回的图像将显示为全黑。

作为最后一点,我发现boardPreviewPicture.snapshotView(afterScreenUpdates: true) 会返回一张图片,但它会使 UITableView 的滚动变得非常缓慢。也许还有另一种解决方法,我可以改用snapshotView()。

【问题讨论】:

  • 您可能需要重新考虑您的设计模式。一方面,在cellForRowAt 中创建/添加/删除单元格的子视图通常是不可取的。 GameManagement.setupBoard() 做了什么?你也许可以在那里简化事情......你为什么要添加/删除UIImageViews?也许还有其他观点(查看您的.subviews.forEach 循环)?也许展示几张你正在拍摄的照片......
  • 我正在为我正在创建的游戏生成现有棋盘的预览。我需要拍摄快照的原因是每个游戏片段都包含多个视图(这是获得我想要的外观所必需的),并且每个棋盘预览有多个游戏片段。因为每个单元格只占据屏幕的一部分,我最终每个屏幕有几百个视图,这使得滚动非常不稳定。通过获取快照,我可以将其限制为更少的视图并获得平滑滚动。

标签: ios swift uitableview uigraphicscontext


【解决方案1】:

我遇到了同样的问题。我注意到,当在tableView(_:cellForRowAt:) 中调用UIGraphicsBeginImageContextWithOptions 时,UIGraphicsGetImageFromCurrentImageContext() 的结果为空白。请注意,在文档中指出UIGraphicsGetImageFromCurrentImageContext:

可以从您应用的任何线程调用此函数。

但是,我发现的解决方案是在主线程中调用它。在您的情况下,也许您可​​以执行以下操作:

DispatchQueue.main.async {
    let gamePicture = PageManagement.pictureTaker(boardPreviewTemplate)
    gamePicture.frame = CGRect(x: 0, y: 0, width: gamePicture.frame.width, height: gamePicture.frame.height)

    //Removing preview board items and replacing with picture
    cell.previewBoard.subviews.forEach({ $0.removeFromSuperview() })
    cell.previewBoard.addSubview(gamePicture)
}

【讨论】:

    猜你喜欢
    • 2015-10-28
    • 2014-03-27
    • 2012-06-03
    • 1970-01-01
    • 2015-02-23
    • 2022-11-12
    • 2022-01-06
    • 1970-01-01
    • 2015-01-03
    相关资源
    最近更新 更多