When using ShareLink in SwiftUI to share an image, the “Save Image” action dismisses not only the share sheet but also the presenting SwiftUI view.
The behavior differs depending on whether the photo library permission alert appears.
Observed behavior:
The first time the user taps Save Image, the system permission alert appears.
After granting permission, the image saves successfully and the share sheet dismisses normally.
On subsequent attempts, the image is saved successfully, but both the share sheet and the presenting view are dismissed unexpectedly.
Expected behavior:
After saving the image, only the share sheet should dismiss.
The presenting SwiftUI view should remain visible.
Steps to Reproduce
Present a SwiftUI view using .sheet.
Inside that view, add a ShareLink configured to export a PNG image using Transferable.
Tap the ShareLink button.
Choose Save Image.
Grant permission the first time (if prompted).
Repeat the action.
Result: On subsequent saves, the share sheet dismisses and the presenting view is dismissed as well.
Sample code
`
internal import System
import UniformTypeIdentifiers
import SwiftUI
struct RootView: View {
@State private var isPresented: Bool = false
var body: some View {
ZStack {
Color.white
Button("Show parent view") {
isPresented = true
}
}
.sheet(isPresented: $isPresented) {
ParentView()
}
}
}
struct ParentView: View {
@State private var isPresented: Bool = false
var body: some View {
NavigationStack {
ZStack {
Color.red.opacity(0.5)
}
.toolbar {
ToolbarItem() {
let name = "\(UUID().uuidString)"
let image = UIImage(named: "after")!
return ShareLink(
item: ShareableImage(image: image, fileName: name),
preview: SharePreview(
name,
image: Image(uiImage: image)
)
) {
Image(uiImage: UIImage(resource: .Icons.share24))
.resizable()
.foregroundStyle(Color.black)
.frame(width: 24, height: 24)
}
}
}
}
}
}
struct ShareableImage: Transferable {
let image: UIImage
let fileName: String
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .png) { item in
let fileURL = FileManager.default.temporaryDirectory
.appendingPathComponent(item.fileName)
.appendingPathExtension("png")
guard let data = item.image.pngData() else {
throw NSError(domain: "ImageEncodingError", code: 0)
}
try data.write(to: fileURL)
return SentTransferredFile(fileURL)
}
}
}
`