Crop shape doesn't appear on iOS18
I'm updating an app I'm working on for iOS18, and have found that SwiftyCrop is broken on iOS18. With the latest version, the crop shape (I'm using square) isn't appearing and you can't pan the image as normal. I was previously using a version from April and it was broken on iOS18 in a different fashion.
I did see this error in the debugger when displaying SwiftyCrop:
[ERROR] Could not create a bookmark: NSError: Cocoa 4097 "connection to service named com.apple.FileProvider"
Hey @jrehbein thanks for noticing and pointing this issue out. I will look into it asap!
Okay I did some testing and I have the issue aswell in one of my apps using the library.
It seems to me however the mentioned console error is unrelated, since the image is loaded properly but the mask shape is just missing completely.
I added the same functionality for picking an image from the library using the PhotosPicker in the demo app. This also prints the same error in the console but the cropping works just fine.
I am still investigating but maybe this issue does not lay in the library itself but in the apps using the library.
Yeah, I had no confidence that the error message was directly related, but just noted that it happened at the time of presenting the cropper in case it was.
Thanks for looking into this!
I can confirm the following now:
- The issue appears in iOS 18.0
- Earlier versions (e.g. iOS 17) do not seem to be affected
- Testing with iOS 18.1 (Beta 4) confirmed the issue to be resolved
In my understanding this is a SwiftUI bug in iOS 18.0. The solution is to update iOS 18.0 to 18.1 once released.
I am leaving this issue open for further notices and so others can find it.
Thanks for verifying that. Unfortunate that it's an Apple bug (add it to the pile), but at least they are fixing this one. I wonder if the fix might actually be in 18.0.1? I'll be testing that out when that is released.
I wonder if this will be fixed on Monday! 😆
Seems to still be an issue in the iOS 18.1 RC that is released since last week
Had an app fail app review this week because this presents on iOS 18.1
Will take a deeper look into this
Okay here's what I figured out with some testing since one of my live apps has the same issue. I managed to fix it. There are two potential issues that might occur depending on how the SwiftyCropView is presented:
- Invisible Mask Issue: The cropping mask might be invisible on physical devices while working fine in simulators when implemented in your app (demo seems to work with no issues)
- Safe Area Issue: The cropping view's buttons might ignore safe areas
Root Cause
These issues are related to the SwiftUI view hierarchy and how SwiftyCropView is presented. The behavior differs based on where in the view hierarchy the .fullScreenCover modifier is placed:
// Approach 1: Presenting on NavigationView level - Mask becomes invisible
var body: some View {
NavigationView {
ScrollView {
// Content
}
}
.fullScreenCover(...) { // ❌ Mask visibility issues
SwiftyCropView(...)
}
// Approach 2: Presenting on Content level - Safe area issues
var body: some View {
NavigationView {
ScrollView {
// Content
}
.fullScreenCover(...) { // ❌ Mask visible but safe area issues
SwiftyCropView(...)
}
}
Solution
To fix both issues, wrap the SwiftyCropView in its own NavigationView when presenting it. This ensures proper mask rendering while maintaining correct safe area handling:
struct YourView: View {
@State private var showImageCropper = false
@State private var imageToEdit: UIImage?
private let cropConfig = SwiftyCropConfiguration(rotateImage: false)
var body: some View {
NavigationView {
ScrollView {
// Content
}
.fullScreenCover(isPresented: $showImageCropper) {
if let image = imageToEdit {
NavigationView { // 👈 Add this wrapper
SwiftyCropView(
imageToCrop: image,
maskShape: .square,
configuration: cropConfig
) { croppedImage in
// Handle cropped image
}
}
}
}
}
}
}
}
Testing
This solution has been verified to work correctly on:
- iPhone 16 Pro Max (physical) running iOS 18.1
- iPhone 16 Pro (simulator) running iOS 18.0 and 18.1
Additional Notes
If you're using SwiftyCrop in a more complex view hierarchy (e.g., with multiple sheets or navigation layers), ensure that the .fullScreenCover modifier is placed at an appropriate level in your view hierarchy to maintain proper presentation context.
Finally got around to testing this. Works for me, thanks!
Hey folks, I had the same issue, and this workaround has helped me.
However, since [NavigationView](https://developer.apple.com/documentation/swiftui/navigationview) is officially deprecated starting iOS 26+, I'm curious how others are planning to future-proof their implementations. Any ideas or migration strategies in mind?
@surajreddykarra I think since NavigationView is deprecated, you could try using NavigationStack. I haven't tried it yet however 🫤