SwiftyCrop icon indicating copy to clipboard operation
SwiftyCrop copied to clipboard

Crop shape doesn't appear on iOS18

Open jrehbein opened this issue 1 year ago • 5 comments

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"

jrehbein avatar Sep 22 '24 04:09 jrehbein

Hey @jrehbein thanks for noticing and pointing this issue out. I will look into it asap!

benedom avatar Sep 22 '24 12:09 benedom

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.

benedom avatar Sep 22 '24 13:09 benedom

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!

jrehbein avatar Sep 22 '24 19:09 jrehbein

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.

benedom avatar Sep 25 '24 13:09 benedom

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.

jrehbein avatar Sep 27 '24 06:09 jrehbein

I wonder if this will be fixed on Monday! 😆

BrendanThompson avatar Oct 23 '24 07:10 BrendanThompson

Seems to still be an issue in the iOS 18.1 RC that is released since last week

benedom avatar Nov 04 '24 17:11 benedom

Had an app fail app review this week because this presents on iOS 18.1

joeycarmello avatar Nov 15 '24 10:11 joeycarmello

Will take a deeper look into this

benedom avatar Nov 15 '24 10:11 benedom

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:

  1. 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)
  2. 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.

benedom avatar Nov 15 '24 12:11 benedom

Finally got around to testing this. Works for me, thanks!

jrehbein avatar Dec 01 '24 04:12 jrehbein

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?

Image

surajreddykarra avatar Aug 01 '25 19:08 surajreddykarra

@surajreddykarra I think since NavigationView is deprecated, you could try using NavigationStack. I haven't tried it yet however 🫤

benedom avatar Sep 02 '25 07:09 benedom