ToggleButton.swift 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /// A button style control that is either on or off.
  2. ///
  3. /// This corresponds to the ``ToggleStyle/button`` toggle style.
  4. struct ToggleButton: ElementaryView, View {
  5. /// The label to show on the toggle button.
  6. private var label: String
  7. /// Whether the button is active or not.
  8. private var active: Binding<Bool>
  9. /// Creates a toggle button that displays a custom label.
  10. ///
  11. /// - Parameters:
  12. /// - label: The label to show on the toggle button.
  13. /// - active: Whether the button is active or not.
  14. public init(_ label: String, isOn active: Binding<Bool>) {
  15. self.label = label
  16. self.active = active
  17. }
  18. func asWidget<Backend: BaseAppBackend>(backend: Backend) -> Backend.Widget {
  19. return backend.createToggle()
  20. }
  21. func computeLayout<Backend: BaseAppBackend>(
  22. _ widget: Backend.Widget,
  23. proposedSize: ProposedViewSize,
  24. environment: EnvironmentValues,
  25. backend: Backend
  26. ) -> ViewLayoutResult {
  27. // TODO: Implement toggle button sizing within SwiftCrossUI so that we
  28. // can delay updating the underlying widget until `commit`.
  29. backend.updateToggle(widget, label: label, environment: environment) { newActiveState in
  30. if active.wrappedValue != newActiveState {
  31. active.wrappedValue = newActiveState
  32. }
  33. }
  34. return ViewLayoutResult.leafView(
  35. size: ViewSize(backend.naturalSize(of: widget))
  36. )
  37. }
  38. func commit<Backend: BaseAppBackend>(
  39. _ widget: Backend.Widget,
  40. layout: ViewLayoutResult,
  41. environment: EnvironmentValues,
  42. backend: Backend
  43. ) {
  44. backend.setState(ofToggle: widget, to: active.wrappedValue)
  45. backend.setSize(of: widget, to: layout.size.vector)
  46. }
  47. }