gualtierofrigerio / ScreenshotSwiftUI

SPM Package to take screenshots of SwiftUI Views
MIT License
22 stars 4 forks source link

Doesn't work with blur() modifier #5

Open dqhieu opened 1 year ago

dqhieu commented 1 year ago

So I have a view like this

ZStack {
  Circle()
    .fill(Color.blue.opacity(0.5))
    .blur(radius: 150)
  MyView()
}

Here's the expected screenshot, but I'm getting this screenshot instead

Expectation Actual
expected actual

So basically when taking screenshot it doesn't render the .blur() modifier of the Circle

Do you have any idea how to fix it?

Thanks for checking

gualtierofrigerio commented 1 year ago

from your screenshot, it looks like it is also ignoring the fill modifier as the color looks different. I suppose the text is in MyView so it looks like is doing a screenshot of the uppermost view, which could be possible. More than blur, I guess It is an issue with ZStack, if you apply blur modifier to another view outside a ZStack does it work?

dqhieu commented 1 year ago

So I tried blur() without using ZStack, and the result is still the same. So I think it's not relevant to ZStack

struct ContentView: View {

  @State var screenshotMaker: ScreenshotMaker?

  var body: some View {
    VStack {
      Image(systemName: "globe")
        .imageScale(.large)
        .foregroundStyle(.tint)
      Text("Hello, world!")
      Button(action: {
        guard let uiImage = screenshotMaker?.screenshot() else { return }
        // share image
      }, label: {
        Text("Screenshot")
      })
      Circle()
        .fill(.blue)
        .blur(radius: 50)
    }
    .padding()
    .screenshotMaker { maker in
      screenshotMaker = maker
    }
  }
}
View Screenshot
Simulator Screenshot - iPhone 14 Pro - 2023-08-02 at 09 42 34 screenshot
gualtierofrigerio commented 1 year ago

good catch, it is not working with blur and I guess it is due to how the screenshot is made via UIGraphicsImageRenderer. If I take it with UIGraphicsGetImageFromCurrentImageContext I can see the blur but I'd need to adapt the screenshot function to take only the correct area. Vacation time is near so I don't know if I'll find time to do it before that, but thanks for reporting this

dqhieu commented 1 year ago

Sadly UIGraphicsGetImageFromCurrentImageContext will be deprecated in iOS 17

gualtierofrigerio commented 1 year ago

oh yes I was opening the project with Xcode 14 so I didn't notice the deprecation message. So anyway this doesn't seem to be an issue related to how SwiftUI renders the blur, but on how the screenshot is made via UIGraphicsImageRenderer