Consider this example
struct MRE: View {
@State var image: UIImage?
@ViewBuilder
func makeView() -> some View {
VStack(spacing: 0) {
Image("cat")
.resizable()
.aspectRatio(contentMode: .fit)
Text("HELLO")
.font(.system(size: 56))
}
.padding()
}
var body: some View {
VStack {
makeView()
if let image = image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
}
Button {
image = makeView().asImage()
} label: {
Text("copy")
}
}
}
}
extension View {
func asImage(scale: CGFloat = 1) -> UIImage {
// Must ignore safe area due to a bug in iOS 15+ https://stackoverflow.com/a/69819567/1011161
let controller = UIHostingController(rootView: edgesIgnoringSafeArea(.top))
let view = controller.view
let targetSize = controller.view.intrinsicContentSize
view?.bounds = CGRect(origin: CGPoint(x: 0, y: 0), size: targetSize)
view?.backgroundColor = .clear
let format = UIGraphicsImageRendererFormat()
format.scale = scale // Ensures 3x-scale images. You can customise this however you like.
let renderer = UIGraphicsImageRenderer(size: targetSize, format: format)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}
It gives the following image, where the image looks exactly right, but the text always come out small. How to fix?