PreferenceModifier.swift 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. extension View {
  2. public func preference<V>(
  3. key: WritableKeyPath<PreferenceValues, V>,
  4. value: V
  5. ) -> some View {
  6. PreferenceModifier(self) { preferences, _ in
  7. var preferences = preferences
  8. preferences[keyPath: key] = value
  9. return preferences
  10. }
  11. }
  12. }
  13. struct PreferenceModifier<Child: View>: View {
  14. var body: TupleView1<Child>
  15. var modification: (PreferenceValues, EnvironmentValues) -> PreferenceValues
  16. init(
  17. _ child: Child,
  18. modification: @escaping (PreferenceValues, EnvironmentValues) -> PreferenceValues
  19. ) {
  20. self.body = TupleView1(child)
  21. self.modification = modification
  22. }
  23. func computeLayout<Backend: BaseAppBackend>(
  24. _ widget: Backend.Widget,
  25. children: any ViewGraphNodeChildren,
  26. proposedSize: ProposedViewSize,
  27. environment: EnvironmentValues,
  28. backend: Backend
  29. ) -> ViewLayoutResult {
  30. var result = body.computeLayout(
  31. widget,
  32. children: children,
  33. proposedSize: proposedSize,
  34. environment: environment,
  35. backend: backend
  36. )
  37. result.preferences = modification(result.preferences, environment)
  38. return result
  39. }
  40. func commit<Backend: BaseAppBackend>(
  41. _ widget: Backend.Widget,
  42. children: any ViewGraphNodeChildren,
  43. layout: ViewLayoutResult,
  44. environment: EnvironmentValues,
  45. backend: Backend
  46. ) {
  47. body.commit(
  48. widget,
  49. children: children,
  50. layout: layout,
  51. environment: environment,
  52. backend: backend
  53. )
  54. }
  55. }