Skip to content

Commit c7a02d4

Browse files
authored
Merge pull request #7 from ShoichiKuraoka/master
fix: effect of ShapeLayer
2 parents 83a632a + 4cc9294 commit c7a02d4

File tree

1 file changed

+72
-48
lines changed

1 file changed

+72
-48
lines changed

ShapeView/Classes/ShapeLayer.swift

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ fileprivate extension CAShapeLayer {
6464

6565
public class ShapeLayer: CAShapeLayer {
6666

67-
private let effectView = UIVisualEffectView()
68-
6967
private let outerShadowLayer = CAShapeLayer()
7068
private let backgroundLayer = CALayer()
7169
private let innerShadowLayer = CAShapeLayer()
70+
private let effectLayer = CAShapeLayer()
71+
private let effectView = UIVisualEffectView()
7272

7373
// The shadow path is drawed by the closure drawShape.
7474
// When the drawShape cloure is updated, the shapePath should be updated.
75-
private var shapePath: UIBezierPath?
75+
private var shapePath = UIBezierPath(rect: .zero)
7676

7777
// The screen path is used for creating the mask to cut the shadow layer.
7878
// When the bounds is updated, it should be updated.
@@ -133,22 +133,38 @@ public class ShapeLayer: CAShapeLayer {
133133
}
134134
}
135135

136-
private var initialized = false
136+
override public init() {
137+
super.init()
138+
initialize()
139+
}
140+
141+
public required init?(coder aDecoder: NSCoder) {
142+
super.init(coder: aDecoder)
143+
initialize()
144+
}
145+
146+
private func initialize() {
147+
addSublayer(outerShadowLayer)
148+
addSublayer(backgroundLayer)
149+
addSublayer(effectLayer)
150+
addSublayer(innerShadowLayer)
151+
152+
backgroundLayer.masksToBounds = true
153+
154+
innerShadowLayer.masksToBounds = true
155+
innerShadowLayer.fillRule = .evenOdd
156+
157+
effectLayer.addSublayer(effectView.layer)
158+
effectLayer.masksToBounds = true
159+
160+
effectView.alpha = 0
161+
}
137162

138163
open override var bounds: CGRect {
139164
didSet {
140165
guard bounds != .zero else {
141166
return
142167
}
143-
if !initialized {
144-
addSublayer(outerShadowLayer)
145-
addSublayer(backgroundLayer)
146-
addSublayer(innerShadowLayer)
147-
effectView.alpha = 0
148-
backgroundLayer.addSublayer(effectView.layer)
149-
initialized = true
150-
}
151-
152168
updateShapePath()
153169
refresh()
154170
}
@@ -165,69 +181,77 @@ public class ShapeLayer: CAShapeLayer {
165181
}
166182

167183
private func refreshInner() {
168-
guard let shapePath = shapePath, let shadow = innerShadow else {
184+
guard let innerShadow = innerShadow else {
169185
innerShadowLayer.isHidden = true
170186
return
171187
}
172188
innerShadowLayer.isHidden = false
173189
innerShadowLayer.frame = bounds
174-
innerShadowLayer.masksToBounds = true
175-
innerShadowLayer.fillRule = .evenOdd
176-
innerShadowLayer.path = { () -> UIBezierPath in
190+
innerShadowLayer.shapeShadow = innerShadow
191+
innerShadowLayer.path = {
177192
let path = UIBezierPath()
178193
path.append(screenPath)
179194
path.append(shapePath)
180-
return path
181-
}().cgPath
182-
innerShadowLayer.shapeShadow = shadow
183-
184-
let cutLayer = CAShapeLayer()
185-
cutLayer.path = shapePath.cgPath
186-
innerShadowLayer.mask = cutLayer
195+
return path.cgPath
196+
}()
197+
innerShadowLayer.mask = {
198+
let cutLayer = CAShapeLayer()
199+
cutLayer.path = shapePath.cgPath
200+
return cutLayer
201+
}()
187202
}
188203

189204
private func refreshOuter() {
190-
guard let shapePath = shapePath, let shadow = outerShadow else {
205+
guard let outerShadow = outerShadow else {
191206
outerShadowLayer.isHidden = true
192207
return
193208
}
194209
outerShadowLayer.isHidden = false
195210
outerShadowLayer.path = shapePath.cgPath
196-
outerShadowLayer.shapeShadow = shadow
197-
198-
let cutLayer = CAShapeLayer()
199-
cutLayer.path = { () -> UIBezierPath in
200-
let path = UIBezierPath()
201-
path.append(shapePath)
202-
path.append(screenPath)
203-
path.usesEvenOddFillRule = true
204-
return path
205-
}().cgPath
206-
cutLayer.fillRule = .evenOdd
207-
outerShadowLayer.mask = cutLayer
211+
outerShadowLayer.shapeShadow = outerShadow
212+
outerShadowLayer.mask = {
213+
let cutLayer = CAShapeLayer()
214+
cutLayer.path = {
215+
let path = UIBezierPath()
216+
path.append(shapePath)
217+
path.append(screenPath)
218+
path.usesEvenOddFillRule = true
219+
return path.cgPath
220+
}()
221+
cutLayer.fillRule = .evenOdd
222+
return cutLayer
223+
}()
208224
}
209225

210226
private func refreshBackground() {
211-
guard let shapePath = shapePath else {
212-
return
213-
}
214227
backgroundLayer.frame = bounds
228+
backgroundLayer.mask = {
229+
let cutLayer = CAShapeLayer()
230+
cutLayer.path = shapePath.cgPath
231+
return cutLayer
232+
}()
233+
}
234+
235+
private func refreshEffect() {
236+
effectLayer.frame = bounds
237+
effectLayer.mask = {
238+
let cutLayer = CAShapeLayer()
239+
cutLayer.path = shapePath.cgPath
240+
return cutLayer
241+
}()
242+
215243
effectView.frame = bounds
216-
let cutLayer = CAShapeLayer()
217-
cutLayer.path = shapePath.cgPath
218-
backgroundLayer.mask = cutLayer
219244
}
220245

221246
private func refresh() {
222247
refreshOuter()
223248
refreshInner()
224249
refreshBackground()
250+
refreshEffect()
225251

226-
if let shapePath = shapePath {
227-
let cutLayer = CAShapeLayer()
228-
cutLayer.path = shapePath.cgPath
229-
didUpdateLayer?(cutLayer)
230-
}
252+
let cutLayer = CAShapeLayer()
253+
cutLayer.path = shapePath.cgPath
254+
didUpdateLayer?(cutLayer)
231255
}
232256

233257
}

0 commit comments

Comments
 (0)