From 1105e3faf426306814bb26f15967085591f5628c Mon Sep 17 00:00:00 2001 From: Hiroshi Kimura Date: Thu, 22 Feb 2024 17:50:52 +0900 Subject: [PATCH] Update InsideOverlay support SwiftUI (#223) --- .../Crop/CropView.CropInsideOverlay.swift | 46 +++++++++++++++++-- .../Shared/Components/Crop/CropView.swift | 15 ++++-- .../Components/Crop/SwiftUICropView.swift | 34 +++++++------- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/Sources/BrightroomUI/Shared/Components/Crop/CropView.CropInsideOverlay.swift b/Sources/BrightroomUI/Shared/Components/Crop/CropView.CropInsideOverlay.swift index 07e8b85c..e6706db5 100644 --- a/Sources/BrightroomUI/Shared/Components/Crop/CropView.CropInsideOverlay.swift +++ b/Sources/BrightroomUI/Shared/Components/Crop/CropView.CropInsideOverlay.swift @@ -131,15 +131,55 @@ extension CropView { @available(iOS 14, *) open class SwiftUICropInsideOverlay: CropInsideOverlayBase { - private let controller: UIHostingController + private let controller: UIHostingController + private let proxy: Proxy + + public init(@ViewBuilder content: @escaping (CropView.State.AdjustmentKind?) -> Content) { + + self.proxy = .init() + self.controller = .init(rootView: Container(proxy: proxy, content: content)) + + controller.view.backgroundColor = .clear + controller.view.preservesSuperviewLayoutMargins = false - public init(controller: UIHostingController) { - self.controller = controller super.init() addSubview(controller.view) AutoLayoutTools.setEdge(controller.view, self) } + open override func didBeginAdjustment(kind: CropView.State.AdjustmentKind) { + proxy.activeKind = kind + } + + open override func didEndAdjustment(kind: CropView.State.AdjustmentKind) { + proxy.activeKind = nil + } + + private final class Proxy: ObservableObject { + + @Published var activeKind: CropView.State.AdjustmentKind? + + } + + private struct Container: View { + + @ObservedObject var proxy: Proxy + + private let content: (CropView.State.AdjustmentKind?) -> Content + + public init( + proxy: Proxy, + content: @escaping (CropView.State.AdjustmentKind?) -> Content + ) { + self.content = content + self.proxy = proxy + } + + var body: some View { + content(proxy.activeKind) + } + } + } public final class RuleOfThirdsView: PixelEditorCodeBasedView { diff --git a/Sources/BrightroomUI/Shared/Components/Crop/CropView.swift b/Sources/BrightroomUI/Shared/Components/Crop/CropView.swift index 8f5adf85..1c1b08fc 100644 --- a/Sources/BrightroomUI/Shared/Components/Crop/CropView.swift +++ b/Sources/BrightroomUI/Shared/Components/Crop/CropView.swift @@ -39,9 +39,18 @@ import BrightroomEngine public final class CropView: UIView, UIScrollViewDelegate { public struct State: Equatable { - public enum AdjustmentKind: Equatable { - case scrollView - case guide + + public struct AdjustmentKind: OptionSet { + + public var rawValue: Int = 0 + + public init(rawValue: Int) { + self.rawValue = rawValue + } + + public static let scrollView = AdjustmentKind(rawValue: 1 << 0) + public static let guide = AdjustmentKind(rawValue: 1 << 1) + } public fileprivate(set) var proposedCrop: EditingCrop? diff --git a/Sources/BrightroomUI/Shared/Components/Crop/SwiftUICropView.swift b/Sources/BrightroomUI/Shared/Components/Crop/SwiftUICropView.swift index a250d8b1..3f91d038 100644 --- a/Sources/BrightroomUI/Shared/Components/Crop/SwiftUICropView.swift +++ b/Sources/BrightroomUI/Shared/Components/Crop/SwiftUICropView.swift @@ -52,24 +52,31 @@ public final class _PixelEditor_WrapperViewController: UIViewC */ @available(iOS 14, *) public struct SwiftUICropView: UIViewControllerRepresentable { - + public typealias UIViewControllerType = _PixelEditor_WrapperViewController - private let cropInsideOverlay: AnyView? + private let cropInsideOverlay: ((CropView.State.AdjustmentKind?) -> AnyView)? private let editingStack: EditingStack private var _rotation: EditingCrop.Rotation? private var _adjustmentAngle: EditingCrop.AdjustmentAngle? private var _croppingAspectRatio: PixelAspectRatio? - public init( + public init( editingStack: EditingStack, - cropInsideOverlay: AnyView? = nil + @ViewBuilder cropInsideOverlay: @escaping (CropView.State.AdjustmentKind?) -> InsideOverlay ) { - self.cropInsideOverlay = cropInsideOverlay self.editingStack = editingStack + self.cropInsideOverlay = { AnyView(cropInsideOverlay($0)) } } - + + public init( + editingStack: EditingStack + ) { + self.cropInsideOverlay = nil + self.editingStack = editingStack + } + public func makeUIViewController(context: Context) -> _PixelEditor_WrapperViewController { let view = CropView(editingStack: editingStack) @@ -77,20 +84,11 @@ public struct SwiftUICropView: UIViewControllerRepresentable { view.isAutoApplyEditingStackEnabled = true let controller = _PixelEditor_WrapperViewController.init(bodyView: view) - + if let cropInsideOverlay = cropInsideOverlay { - - let hosting = UIHostingController.init(rootView: cropInsideOverlay) - - hosting.view.backgroundColor = .clear - hosting.view.preservesSuperviewLayoutMargins = false - - view.setCropInsideOverlay(CropView.SwiftUICropInsideOverlay(controller: hosting)) - - controller.addChild(hosting) - hosting.didMove(toParent: controller) + view.setCropInsideOverlay(CropView.SwiftUICropInsideOverlay(content: cropInsideOverlay)) } - + return controller }