gpt4 book ai didi

swift - 截取 UICollectionView 的全部内容

转载 作者:搜寻专家 更新时间:2023-10-31 22:34:39 27 4
gpt4 key购买 nike

我正在开发的应用程序使用 Collection View 单元格向用户显示数据。我希望用户能够共享单元格中包含的数据,但通常有太多单元格无法尝试调整大小并适合单个 iPhone 屏幕大小的窗口并获取屏幕截图。

所以我遇到的问题是试图获取 Collection View 中所有单元格的图像,包括屏幕上和屏幕外。我知道屏幕外的单元格实际上并不存在,但我会对一种伪造图像并绘制数据的方法感兴趣(如果可能的话)。

简而言之,有没有一种方法可以使用 Swift 在屏幕上和屏幕外以编程方式从 Collection View 及其包含的单元格创建图像?

最佳答案

更新

如果内存不是问题:

mutating func screenshot(scale: CGFloat) -> UIImage {
let currentSize = frame.size
let currentOffset = contentOffset // temp store current offset

frame.size = contentSize
setContentOffset(CGPointZero, animated: false)

// it might need a delay here to allow loading data.

let rect = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.mainScreen().scale)
self.drawViewHierarchyInRect(rect, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

frame.size = currentSize
setContentOffset(currentOffset, animated: false)

return resizeUIImage(image, scale: scale)
}

这对我有用:

github link -> 包含最新的代码

getScreenshotRects 创建要滚动到的偏移量和要捕获的帧。 (命名不完善)

takeScreenshotAtPoint 滚动到该点,设置延迟以允许重绘,截取屏幕截图并通过完成处理程序返回。

stitchImages 创建一个与内容大小相同的矩形,并在其中绘制所有图像。

makeScreenshotsUIImage 的嵌套数组上使用 didSet 和一个计数器来创建所有图像,同时等待完成。完成后,它会触发自己的完成处理程序。

基本部分:

  • 滚动 Collection View -> 有效
  • 截取延迟重绘的屏幕截图 -> 有效
  • 裁剪重叠的图像 -> 显然不需要
  • 拼接所有图像 -> 有效
  • 基础数学 -> 有效
  • 当所有这些发生时,可能会卡住屏幕或隐藏(这不在我的回答中)

代码:

protocol ScrollViewImager {

var bounds : CGRect { get }

var contentSize : CGSize { get }

var contentOffset : CGPoint { get }

func setContentOffset(contentOffset: CGPoint, animated: Bool)

func drawViewHierarchyInRect(rect: CGRect, afterScreenUpdates: Bool) -> Bool
}

extension ScrollViewImager {

func screenshot(completion: (screenshot: UIImage) -> Void) {

let pointsAndFrames = getScreenshotRects()
let points = pointsAndFrames.points
let frames = pointsAndFrames.frames

makeScreenshots(points, frames: frames) { (screenshots) -> Void in
let stitched = self.stitchImages(images: screenshots, finalSize: self.contentSize)
completion(screenshot: stitched!)
}

}

private func makeScreenshots(points:[[CGPoint]], frames : [[CGRect]],completion: (screenshots: [[UIImage]]) -> Void) {

var counter : Int = 0

var images : [[UIImage]] = [] {
didSet {
if counter < points.count {
makeScreenshotRow(points[counter], frames : frames[counter]) { (screenshot) -> Void in
counter += 1
images.append(screenshot)
}
} else {
completion(screenshots: images)
}
}
}

makeScreenshotRow(points[counter], frames : frames[counter]) { (screenshot) -> Void in
counter += 1
images.append(screenshot)
}

}

private func makeScreenshotRow(points:[CGPoint], frames : [CGRect],completion: (screenshots: [UIImage]) -> Void) {

var counter : Int = 0

var images : [UIImage] = [] {
didSet {
if counter < points.count {
takeScreenshotAtPoint(point: points[counter]) { (screenshot) -> Void in
counter += 1
images.append(screenshot)
}
} else {
completion(screenshots: images)
}
}
}

takeScreenshotAtPoint(point: points[counter]) { (screenshot) -> Void in
counter += 1
images.append(screenshot)
}

}

private func getScreenshotRects() -> (points:[[CGPoint]], frames:[[CGRect]]) {

let vanillaBounds = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)

let xPartial = contentSize.width % bounds.size.width
let yPartial = contentSize.height % bounds.size.height

let xSlices = Int((contentSize.width - xPartial) / bounds.size.width)
let ySlices = Int((contentSize.height - yPartial) / bounds.size.height)

var currentOffset = CGPoint(x: 0, y: 0)

var offsets : [[CGPoint]] = []
var rects : [[CGRect]] = []

var xSlicesWithPartial : Int = xSlices

if xPartial > 0 {
xSlicesWithPartial += 1
}

var ySlicesWithPartial : Int = ySlices

if yPartial > 0 {
ySlicesWithPartial += 1
}

for y in 0..<ySlicesWithPartial {

var offsetRow : [CGPoint] = []
var rectRow : [CGRect] = []
currentOffset.x = 0

for x in 0..<xSlicesWithPartial {

if y == ySlices && x == xSlices {
let rect = CGRect(x: bounds.width - xPartial, y: bounds.height - yPartial, width: xPartial, height: yPartial)
rectRow.append(rect)

} else if y == ySlices {
let rect = CGRect(x: 0, y: bounds.height - yPartial, width: bounds.width, height: yPartial)
rectRow.append(rect)

} else if x == xSlices {
let rect = CGRect(x: bounds.width - xPartial, y: 0, width: xPartial, height: bounds.height)
rectRow.append(rect)

} else {
rectRow.append(vanillaBounds)
}

offsetRow.append(currentOffset)

if x == xSlices {
currentOffset.x = contentSize.width - bounds.size.width
} else {
currentOffset.x = currentOffset.x + bounds.size.width
}
}
if y == ySlices {
currentOffset.y = contentSize.height - bounds.size.height
} else {
currentOffset.y = currentOffset.y + bounds.size.height
}

offsets.append(offsetRow)
rects.append(rectRow)

}

return (points:offsets, frames:rects)

}

private func takeScreenshotAtPoint(point point_I: CGPoint, completion: (screenshot: UIImage) -> Void) {
let rect = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)
let currentOffset = contentOffset
setContentOffset(point_I, animated: false)

delay(0.001) {

UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.mainScreen().scale)
self.drawViewHierarchyInRect(rect, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()


self.setContentOffset(currentOffset, animated: false)
completion(screenshot: image)
}
}

private func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}


private func crop(image image_I:UIImage, toRect rect:CGRect) -> UIImage? {

guard let imageRef: CGImageRef = CGImageCreateWithImageInRect(image_I.CGImage, rect) else {
return nil
}
return UIImage(CGImage:imageRef)
}

private func stitchImages(images images_I: [[UIImage]], finalSize : CGSize) -> UIImage? {

let finalRect = CGRect(x: 0, y: 0, width: finalSize.width, height: finalSize.height)

guard images_I.count > 0 else {
return nil
}

UIGraphicsBeginImageContext(finalRect.size)

var offsetY : CGFloat = 0

for imageRow in images_I {

var offsetX : CGFloat = 0

for image in imageRow {

let width = image.size.width
let height = image.size.height


let rect = CGRect(x: offsetX, y: offsetY, width: width, height: height)
image.drawInRect(rect)

offsetX += width

}

offsetX = 0

if let firstimage = imageRow.first {
offsetY += firstimage.size.height
} // maybe add error handling here
}

let stitchedImages = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

return stitchedImages
}
}

extension UIScrollView : ScrollViewImager {

}

关于swift - 截取 UICollectionView 的全部内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32772476/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com