VibrancyEffectModifier.swift 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /**
  2. * SwiftUIVisualEffects
  3. * Copyright © 2020 Lucas Brown
  4. */
  5. import SwiftUI
  6. /// Creates a vibrancy effect.
  7. public struct VibrancyEffectModifier: ViewModifier {
  8. public init() {}
  9. public func body(content: Content) -> some View {
  10. content
  11. // Hide the original content, keeping its intrinsic content size.
  12. .hidden()
  13. // Overlay the modified content.
  14. .overlay(_VibrancyVisualEffectViewRepresentable(content: content))
  15. }
  16. }
  17. fileprivate struct _VibrancyVisualEffectViewRepresentable<Content: View>: UIViewRepresentable {
  18. init(content: Content) {
  19. self.content = content
  20. }
  21. func makeUIView(context: Context) -> UIVisualEffectView {
  22. let blurEffect = UIBlurEffect(style: context.environment.blurEffectStyle)
  23. let visualEffectView = UIVisualEffectView()
  24. // Set `visualEffectView`'s `effect`.
  25. if let vibrancyEffectStyle = context.environment.vibrancyEffectStyle {
  26. visualEffectView.effect = UIVibrancyEffect(blurEffect: blurEffect, style: vibrancyEffectStyle)
  27. } else {
  28. visualEffectView.effect = UIVibrancyEffect(blurEffect: blurEffect)
  29. }
  30. // Embed `content` in `visualEffectView`'s `contentView`.
  31. let hostingControllerView = UIHostingController(rootView: content).view!
  32. // Center `hostingControllerView`'s frame (at the cost of losing its intrinsic content size).
  33. hostingControllerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  34. hostingControllerView.backgroundColor = .clear
  35. visualEffectView.contentView.addSubview(hostingControllerView)
  36. return visualEffectView
  37. }
  38. func updateUIView(_ uiView: UIVisualEffectView, context: Context) {}
  39. private let content: Content
  40. }