-
-
Notifications
You must be signed in to change notification settings - Fork 295
/
CropView.CropOutsideOverlay.swift
133 lines (93 loc) 路 3.33 KB
/
CropView.CropOutsideOverlay.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// CropView.CropOutsideOverlay.swift
// PixelEditor
//
// Created by Muukii on 2021/03/03.
// Copyright 漏 2021 muukii. All rights reserved.
//
import UIKit
import SwiftUI
extension CropView {
open class CropOutsideOverlayBase: PixelEditorCodeBasedView {
open func didBeginAdjustment(kind: CropView.State.AdjustmentKind) {
}
open func didEndAdjustment(kind: CropView.State.AdjustmentKind) {
}
}
public final class CropOutsideOverlayBlurredView: CropOutsideOverlayBase {
private let effectView: UIVisualEffectView
private let dimmingView: UIView
private var currentAnimator: UIViewPropertyAnimator?
public init(
blurEffect: UIBlurEffect = UIBlurEffect(style: .dark),
dimmingColor: UIColor = .init(white: 0, alpha: 0.6)
) {
self.effectView = UIVisualEffectView(effect: blurEffect)
self.dimmingView = UIView()&>.do {
$0.backgroundColor = dimmingColor
}
super.init(frame: .zero)
addSubview(dimmingView)
addSubview(effectView)
AutoLayoutTools.setEdge(dimmingView, self)
AutoLayoutTools.setEdge(effectView, self)
}
public override func didBeginAdjustment(kind: CropView.State.AdjustmentKind) {
if kind == .guide {
currentAnimator?.stopAnimation(true)
currentAnimator = UIViewPropertyAnimator(duration: 0.6, dampingRatio: 1) { [weak self] in
self?.effectView.alpha = 0
}&>.do {
$0.startAnimation()
}
}
}
public override func didEndAdjustment(kind: CropView.State.AdjustmentKind) {
if kind == .guide {
currentAnimator?.stopAnimation(true)
currentAnimator = UIViewPropertyAnimator(duration: 0.6, dampingRatio: 1) { [weak self] in
self?.effectView.alpha = 1
}&>.do {
$0.startAnimation(afterDelay: 1)
}
}
}
}
@available(iOS 14, *)
open class SwiftUICropOutsideOverlay<Content: View>: CropOutsideOverlayBase {
private let controller: UIHostingController<Container>
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
super.init(frame: .zero)
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)
}
}
}
}