Closed iDevelopper closed 4 years ago
Sadly, it seems like a limitation of Apple. Snapshotting visual effect views is not recommended. It used to look better in the past, but in recent years, it looks bad.
Portal views are different (and private!). The allow rendering parts of the hierarchy in different places, without ripping them from their actual position in hierarchy. But it’s very limited. For example, not possible to render the same view in two different places, unlike snapshots. Apple uses it in interaction previews, for example.
Hope you are well too.
Thanks a lot for your answer. Can _UIPortalView support a sourceRect?? instead of sourceView? Be well!
Thanks,
And unfortunately, Apple cannot provide a reliable API for these screenshots, then! Even more strange, if I capture a toolbar from a navigation controller with snapshotViewAfterScreenUpdates, it works, but if I capture a toolbar that I added myself on a view, it does not work, it is completely transparent, except if I set a background color to the toolbar I added. However, looking in debug view hierarchy these two toolbar seem to be similar.
They do not say everything to us ! They are not transparent, them! :-)
You can fake it by adding a visual effect view under your snapshot.
Yes but with what effect? In the debug view hierarchy, if I look at the visualEffectView of the toolbar, effect = none.
On iOS 13, it’s easy. Set the effect to UIBlurEffectStyleSystemChromeMaterial
. On previous systems, it’s harder to find a match, and may even be impossible.
I will test, fortunately, the snapshot is bugged only on iOS 13 and I need it because of the new modal presentation style...
Thanks, it works, I don't understand why (did you work at Apple?). But no for tabBar of UITabBarController. So, this is what I did:
private func setupBottomBarForPresentation() -> UIView? {
#if targetEnvironment(macCatalyst)
return nil
#else
if UIDevice.current.userInterfaceIdiom == .pad {
if self.dropShadowViewFor(presentingVC.view) != nil {
return nil
}
}
if ProcessInfo.processInfo.operatingSystemVersion.majorVersion < 13 {
return nil
}
var imageRect = self.presentingVC.defaultFrameForBottomBar()
imageRect.origin.y = 0
imageRect.size.height += self.presentingVC.insetsForBottomBar().bottom
//for debug
//let image = presentingVC.bottomBar.makeSnapshot(from: imageRect)
if let view = self.presentingVC.bottomBar.resizableSnapshotView(from: imageRect, afterScreenUpdates: false, withCapInsets: .zero) {
if self.presentingVC is UITabBarController {
return view
}
if #available(iOS 13.0, *) {
let blurEffect = UIBlurEffect(style: .systemChromeMaterial)
let effectView = UIVisualEffectView(effect: blurEffect)
effectView.frame = view.bounds
effectView.contentView.addSubview(view)
return effectView
}
return view
}
return nil
#endif
}
@LeoNatan , I hope you are well despite these circumstances. This is just a question please? Do you know why snapshotViewAfterScreenUpdates: method does not capture a toolbar view correctly ? The capture view show only items and everything else is clear. I saw that your framework version 3, you use the private UIView _UIPortalView. Is it for a workaround? Thanks,