快速旋转视图并将其转换为图像的最佳方法是什么?

时间:2020-02-21 18:20:37

标签: ios swift autolayout

我被赋予了在Swift中创建动态“票证”的任务。我已从我们的服务器API中传递了票证编号,金额等,并生成了条形码以​​及与此票证关联的所有标签。我能够毫无问题地生成所有必要的数据。

问题

问题在于布局。我需要这张票的缩略图视图以及全屏视图。这似乎最好通过将视图转换为图像来完成(对吗?),因为它允许诸如缩放,具有缩略图视图等功能。问题的主要原因是需要放置票证标签和条形码垂直或基本上在横向模式下显示。

我尝试过的

UIGraphicsBeginImageContext

我已经使用UIGraphicsBeginImageContext()和相关的API手动创建了图像。这使我可以翻转每个视图并将其转换为图像。但是,这种方法迫使我为每个视图手动创建框架,并且失去了所有准确性,而且当我必须在空白图像上添加10-15个标签时,这种方法似乎不是正确的方法。

AutoLayout

接下来,我尝试使用自动布局将所有内容布置在UIView中,并将CGAffineTransform应用于每个视图,然后将整个视图转换为图像。除了我失去精度并且无法正确对齐视图之外,这似乎可以正常工作。 CGAffineTransform完全摆脱了约束,我不得不尝试使用约束常量,直到我使视图看起来有些正确为止,即使那样也不能完全将其转换为所有设备尺寸。

风景模式

最后,我尝试正常布置视图,并强制视图进入横向模式。除了由于我的应用程序仅支持纵向模式而引起的许多问题之外,我还可以在呈现视图时使它正常工作,但是我不知道如何获取应该在显示票证视图之前显示的缩略图视图处于横向模式。如果我尝试这样做,缩略图将以纵向模式而不是横向模式显示。

你们对实现此目标的更好方法有任何想法,还是我应该坚持尝试并尝试解决所有错误的方法之一?我可以根据需要提供代码,但是其中包含很多内容,所以我不想在不需要的情况下将所有代码都放在这里。

以下是我需要创建的示例,除了需要在此处添加其他标签(例如签发日期,到期日期等)之外。

enter image description here

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

您问:

快速旋转视图并将其转换为图像的最佳方法是什么?

如果要创建视图的旋转快照,请将rotatetranslateBy应用于上下文:

func clockwiseSnapshot(of subview: UIView) -> UIImage {
    var rect = subview.bounds
    swap(&rect.size.width, &rect.size.height)
    return UIGraphicsImageRenderer(bounds: rect).image { context in
        context.cgContext.rotate(by: .pi / 2)
        context.cgContext.translateBy(x: 0, y: -rect.width)
        subview.drawHierarchy(in: subview.bounds, afterScreenUpdates: true)
    }
}

func counterClockwiseSnapshot(of subview: UIView) -> UIImage {
    var rect = subview.bounds
    swap(&rect.size.width, &rect.size.height)
    return UIGraphicsImageRenderer(bounds: rect).image { context in
        context.cgContext.rotate(by: -.pi / 2)
        context.cgContext.translateBy(x: -rect.height, y: 0)
        subview.drawHierarchy(in: subview.bounds, afterScreenUpdates: true)
    }
}

很明显,如果您希望Data与图像相关联,请改用pngDatajpegData

func clockwiseSnapshotData(of subview: UIView) -> Data {
    var rect = subview.bounds
    swap(&rect.size.width, &rect.size.height)
    return UIGraphicsImageRenderer(bounds: rect).pngData { context in
        context.cgContext.rotate(by: .pi / 2)
        context.cgContext.translateBy(x: 0, y: -rect.width)
        subview.drawHierarchy(in: subview.bounds, afterScreenUpdates: true)
    }
}

func counterClockwiseSnapshotData(of subview: UIView) -> Data {
    var rect = subview.bounds
    swap(&rect.size.width, &rect.size.height)
    return UIGraphicsImageRenderer(bounds: rect).pngData { context in
        context.cgContext.rotate(by: -.pi / 2)
        context.cgContext.translateBy(x: -rect.height, y: 0)
        subview.drawHierarchy(in: subview.bounds, afterScreenUpdates: true)
    }
}

如果您实际上不需要图像,而只想在UI中旋转图像,则对包含所有这些子视图的视图应用transform

someView.transform = .init(rotationAngle: .pi / 2)
相关问题