In swiftui app taking snapshot of view with images and text.Then on one button saving it in gallery and other button dislaying share sheet with uiactivitycontroller. Image is not displaying first time and sheet is blank. working fine after second time. in takescreenshot method screenshot is there but in sheet method screenshot image is not there. Please help
struct ShareImageView: View {
@State var shouldHideHeaderBack: Bool = false
@AppStorage(“username”) var userName: String?
@State var selectImageByUser: UIImage?
@State private var showingShareSheet = false
@State private var snapshotImage: UIImage?
@State private var isSnapshotReady = false // Track if snapshot is ready
var body: some View {
ZStack(alignment: .bottom) {
VStack(alignment: .leading) {
HeaderView(
isBack: true,
shouldHideBack: self.$shouldHideHeaderBack,
isRightButton: true,
title: "Hola Amigos",
isTitle: false,
rightImage: "save",
headerColor: .clear,
backColor: .themeBlack,
rightButtonClicked: {
let size = CGSize(width: UIScreen.main.bounds.width - 40, height: isiPad() ? 1000 + 70 : 448 + 45)
let userImageView = UserImageView(image: selectImageByUser, userName: userName)
snapshotImage = userImageView.snapshot(size: size)
print("Snapshot image is1", snapshotImage ?? UIImage())
if let image = snapshotImage {
let imageSaver = ImageSaver()
imageSaver.writeToPhotoAlbum(image: image)
}
},
secondrightButtonClicked: {
print("Print button clicked view")
if let imageData = UserDefaults.standard.data(forKey: "snapimage") {
self.snapshotImage = UIImage(data: imageData)
print("snap image in button",self.snapshotImage)
if isSnapshotReady { // Check if snapshot is ready
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
showingShareSheet.toggle()
}
}
} else {
print("No image found in button")
}
}
)
.background(Color.themeWhite)
VStack {
ScrollView(.vertical) {
VStack {
UserImageView(image: self.selectImageByUser, userName: userName)
.background(Color.themeBlack)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
takeSnapshot()
}
}
VStack {
HStack {
CustomButtonView(buttonClicked: {
if let imageData = UserDefaults.standard.data(forKey: "snapimage") {
self.snapshotImage = UIImage(data: imageData)
print("snap image in button",self.snapshotImage)
if isSnapshotReady { // Check if snapshot is ready
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
showingShareSheet.toggle()
}
}
} else {
print("No image found in button")
}
}, title: "Share")
}
.frame(width: UIScreen.screenWidth-40,height: 100)
.padding(.horizontal, 16)
}
.sheet(isPresented: $showingShareSheet) {
if let snapshotImage = snapshotImage {
ActivityViewController(activityItems: [snapshotImage.fixedOrientation()])
} else {
let _ = print("no image in snapshot")
}
}
Spacer()
}
}
}
.frame(maxWidth: .infinity)
}
}
.edgesIgnoringSafeArea(.all)
.background(Color.themeBlack)
.navigationBarHidden(true)
.onAppear {
self.takeSnapshot()
}
}
func takeSnapshot() {
let size = CGSize(width: UIScreen.main.bounds.width - 40, height: isiPad() ? 1000 + 70 : 600 + 45)
let userImageView = UserImageView(image: selectImageByUser, userName: userName)
snapshotImage = userImageView.snapshot(size: size)
if let _ = snapshotImage {
isSnapshotReady = true // Set snapshot ready flag
UserDefaults.standard.setValue(snapshotImage?.pngData(), forKey: "snapimage")
} else {
print("Snapshot image capture failed.")
}
print("take snaphot",snapshotImage)
}
}
struct UserImageView: View {
var image: UIImage?
var userName: String?
var body: some View {
VStack {
ZStack {
Image("template")
.resizable()
.frame(width: UIScreen.main.bounds.width - 40, height: isiPad() ? 1000 : 600)
VStack {
Spacer()
.frame(height: 180)
Image(uiImage: image ?? UIImage())
.resizable()
.scaledToFill()
.frame(width: 100, height: 100)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
Text(userName ?? "Hello User")
.font(Font.interDisplay(.bold, size: 30))
.foregroundColor(.black)
.padding(.top, 8)
Spacer()
}
.frame(width: UIScreen.main.bounds.width - 100)
.padding(.bottom, 16)
}
.frame(maxWidth: .infinity, alignment: .top)
}
}
}