Skip to content

Commit 5ed29a4

Browse files
committed
Performance improved - Bug in blur fixed. Layout Fixed in example. Blurring in background thread
1 parent 0c2c82c commit 5ed29a4

9 files changed

Lines changed: 101 additions & 39 deletions

File tree

ShadowView.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
#
1717

1818
s.name = "ShadowView"
19-
s.version = '1.0.3'
19+
s.version = '1.1'
2020
s.summary = "ShadowView makes view's shadow implementation easy and sweet"
2121

2222
# This description is used to generate tags and improve search results.
@@ -65,7 +65,7 @@ DESC
6565
#
6666

6767
# s.platform = :ios
68-
s.ios.deployment_target = '8.1'
68+
s.ios.deployment_target = '8.1'
6969

7070
# When using multiple platforms
7171
# s.ios.deployment_target = "5.0"

ShadowView/ShadowView/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.0.2</string>
18+
<string>1.1</string>
1919
<key>CFBundleVersion</key>
2020
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
<key>NSPrincipalClass</key>

ShadowView/ShadowView/ShadowView+BlurProcess.swift

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,45 @@ extension ShadowView{
2424
self.insertSubview(imageView,at:0)
2525
}
2626

27+
28+
2729
func updateShadow(){
2830

29-
blurWork?.cancel()
30-
self.shadowImageView.alpha = 0
31-
blurWork = DispatchWorkItem(qos: DispatchQoS.userInteractive, flags: DispatchWorkItemFlags.noQoS) {
31+
self.shadowImageView.image = nil
32+
DispatchQueue.global(qos: DispatchQoS.QoSClass.utility).async {
3233
self.createLayerImage()
3334
}
34-
blurWork?.perform()
3535
}
3636

3737
private func createLayerImage(){
3838

3939
let image = self.asImage
40-
41-
4240
let containerLayer = CALayer()
4341
let imageSize = image.size
44-
containerLayer.frame = CGRect(origin: .zero, size: imageSize.scaled(by: scaleImageConstant))
42+
containerLayer.frame = CGRect(origin: .zero, size: imageSize.scaled(by:self.scaleImageConstant))
4543
containerLayer.backgroundColor = UIColor.clear.cgColor
4644
let blurImageLayer = CALayer()
4745
blurImageLayer.frame = CGRect(origin: .zero,size: imageSize)
4846
blurImageLayer.position = CGPoint(x:containerLayer.bounds.midX,y:containerLayer.bounds.midY)
49-
blurImageLayer.contents = image.cgImage
47+
blurImageLayer.contents = image.applyBlurWithRadius(0, tintColor: self.shadowColor, saturationDeltaFactor: self.shadowSaturation)?.cgImage
5048

51-
blurImageLayer.masksToBounds = true
49+
blurImageLayer.masksToBounds = false
5250
containerLayer.addSublayer(blurImageLayer)
53-
5451
let containerImage = containerLayer.asImage
55-
52+
53+
5654
let resizeImageConstant :CGFloat = 1
5755
guard let resizedContainerImage = containerImage.resized(withPercentage: resizeImageConstant),
58-
let blurredImage = resizedContainerImage.applyBlurWithRadius(blurRadius, tintColor: self.shadowTintColor, saturationDeltaFactor: self.shadowSaturation)
56+
let blurredImage = resizedContainerImage.applyBlur(blurRadius: self.blurRadius)
5957
else {
6058
return
6159
}
6260

6361
self.layer.masksToBounds = false
62+
6463
DispatchQueue.main.async {
6564
self.shadowImageView?.image = blurredImage
66-
self.shadowImageView.alpha = 1
6765
}
66+
6867
}
6968
}

ShadowView/ShadowView/ShadowView.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88

99
import UIKit
1010

11-
@IBDesignable
1211
class ShadowView: UIView {
1312

13+
lazy var blurOperationQueue : OperationQueue = {
14+
let operationQueue = OperationQueue.init()
15+
operationQueue.maxConcurrentOperationCount = 1
16+
operationQueue.qualityOfService = .userInteractive
17+
return operationQueue
18+
}()
1419
internal var blurWork : DispatchWorkItem?
1520
internal var blurRadius :CGFloat = 5.0
1621
var shadowImageView : UIImageView!
@@ -40,10 +45,12 @@ class ShadowView: UIView {
4045
self.updateShadow()
4146
}
4247
}
43-
44-
@IBInspectable var shadowTintColor : UIColor = .clear{
45-
didSet{
46-
self.updateShadow()
48+
private var shadowTintColor : UIColor?
49+
override var shadowColor: UIColor?{
50+
get{
51+
return shadowTintColor
52+
}set{
53+
self.shadowTintColor = newValue
4754
}
4855
}
4956

@@ -81,8 +88,9 @@ class ShadowView: UIView {
8188
override func layoutSubviews() {
8289
super.layoutSubviews()
8390

84-
self.shadowImageView.center = CGPoint(x:self.bounds.midX + self.shadowOffset.width,y:self.bounds.midY + self.shadowOffset.height)
8591
self.shadowImageView.frame.size = self.frame.size.scaled(by: correctShadowScale)
92+
self.shadowImageView.center = CGPoint(x:self.bounds.midX + self.shadowOffset.width,y:self.bounds.midY + self.shadowOffset.height)
93+
8694
}
8795

8896
}

ShadowView/ShadowView/UIImage+Size.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
//
88

99
import UIKit
10+
import CoreGraphics
1011

1112
extension UIImage{
1213

13-
1414
/// Resize the image to a centain percentage
1515
///
1616
/// - Parameter percentage: Percentage value
@@ -30,6 +30,34 @@ extension UIImage{
3030
draw(in: CGRect(origin: .zero, size: canvasSize))
3131
return UIGraphicsGetImageFromCurrentImageContext()
3232
}
33+
34+
35+
func applyBlur(blurRadius:CGFloat) -> UIImage?{
36+
37+
guard let ciImage = CIImage.init(image: self) else{return nil}
38+
39+
if let filter = CIFilter(name: "CIGaussianBlur") {
40+
41+
filter.setValue(ciImage, forKey: kCIInputImageKey)
42+
filter.setValue(blurRadius, forKey: kCIInputRadiusKey)
43+
let eaglContext =
44+
EAGLContext(api: EAGLRenderingAPI.openGLES3)
45+
?? EAGLContext(api: EAGLRenderingAPI.openGLES2)
46+
?? EAGLContext(api: EAGLRenderingAPI.openGLES1)
47+
48+
let context = eaglContext == nil ?
49+
CIContext.init(options: nil)
50+
: CIContext.init(eaglContext: eaglContext!)
51+
52+
if let output = filter.outputImage,
53+
let cgimg = context.createCGImage(output, from: ciImage.extent)
54+
{
55+
return UIImage(cgImage: cgimg)
56+
}
57+
}
58+
59+
return nil
60+
}
3361
}
3462

3563

ShadowView/ShadowView/UIView+Shadow.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import UIKit
1010

11-
@IBDesignable extension UIView{
11+
extension UIView{
1212

1313
@IBInspectable public var shadowRadius : CGFloat{
1414
set{
@@ -29,6 +29,7 @@ import UIKit
2929
}
3030
}
3131

32+
3233
@IBInspectable public var shadowColor : UIColor?{
3334
set{
3435
self.layer.shadowColor = newValue?.cgColor

ShadowView/ShadowViewExample/Base.lproj/Main.storyboard

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="2yo-QA-Q5K">
33
<device id="retina4_7" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
@@ -34,7 +34,7 @@
3434
<rect key="frame" x="0.0" y="0.0" width="164" height="164"/>
3535
</imageView>
3636
</subviews>
37-
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
37+
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
3838
<constraints>
3939
<constraint firstItem="vHf-yD-evt" firstAttribute="leading" secondItem="Qad-Aw-0dt" secondAttribute="leading" id="F8S-mD-Gx6"/>
4040
<constraint firstItem="vHf-yD-evt" firstAttribute="top" secondItem="Qad-Aw-0dt" secondAttribute="top" id="NLP-rv-hKW"/>
@@ -55,7 +55,7 @@
5555
</view>
5656
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6Ol-O2-TVX">
5757
<rect key="frame" x="177.5" y="0.0" width="0.0" height="163.5"/>
58-
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
58+
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
5959
</view>
6060
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.jpg" translatesAutoresizingMaskIntoConstraints="NO" id="lUd-IE-JvU">
6161
<rect key="frame" x="191.5" y="0.0" width="163.5" height="163.5"/>
@@ -145,6 +145,13 @@
145145
<action selector="CHANGEiMAGE:" destination="BYZ-38-t0r" eventType="touchUpInside" id="NQj-UR-3dy"/>
146146
</connections>
147147
</button>
148+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6L8-Zs-6ak">
149+
<rect key="frame" x="154" y="105.5" width="46" height="30"/>
150+
<state key="normal" title="Example 2"/>
151+
<connections>
152+
<segue destination="eyZ-MG-Krp" kind="show" id="N3F-ta-bli"/>
153+
</connections>
154+
</button>
148155
</subviews>
149156
</stackView>
150157
</subviews>
@@ -158,6 +165,7 @@
158165
<constraint firstItem="aRm-CH-5SG" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="10" id="z7B-Gz-Hns"/>
159166
</constraints>
160167
</view>
168+
<navigationItem key="navigationItem" id="3O5-fH-0lt"/>
161169
<connections>
162170
<outlet property="exampleView" destination="Qad-Aw-0dt" id="mbP-Vw-Wru"/>
163171
<outlet property="imageviEW" destination="vHf-yD-evt" id="wMS-ko-wIC"/>
@@ -166,7 +174,7 @@
166174
</viewController>
167175
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
168176
</objects>
169-
<point key="canvasLocation" x="32.799999999999997" y="37.331334332833585"/>
177+
<point key="canvasLocation" x="972" y="37.331334332833585"/>
170178
</scene>
171179
<!--Example Prog View Controller-->
172180
<scene sceneID="aLN-2f-fD6">
@@ -179,19 +187,30 @@
179187
<view key="view" contentMode="scaleToFill" id="BGP-dz-rCo">
180188
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
181189
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
182-
<subviews>
183-
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OUB-oa-7c3">
184-
<rect key="frame" x="60" y="173" width="272" height="204"/>
185-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
186-
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
187-
</view>
188-
</subviews>
189190
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
190191
</view>
191192
</viewController>
192193
<placeholder placeholderIdentifier="IBFirstResponder" id="t1F-hl-Peh" userLabel="First Responder" sceneMemberID="firstResponder"/>
193194
</objects>
194-
<point key="canvasLocation" x="757.60000000000002" y="36.431784107946029"/>
195+
<point key="canvasLocation" x="1696.8" y="36.431784107946029"/>
196+
</scene>
197+
<!--Navigation Controller-->
198+
<scene sceneID="6Yb-BS-Y7d">
199+
<objects>
200+
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="2yo-QA-Q5K" sceneMemberID="viewController">
201+
<toolbarItems/>
202+
<navigationBar key="navigationBar" contentMode="scaleToFill" id="1wj-Bh-OUo">
203+
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
204+
<autoresizingMask key="autoresizingMask"/>
205+
</navigationBar>
206+
<nil name="viewControllers"/>
207+
<connections>
208+
<segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="ejb-XO-rg0"/>
209+
</connections>
210+
</navigationController>
211+
<placeholder placeholderIdentifier="IBFirstResponder" id="Atv-8L-pkd" userLabel="First Responder" sceneMemberID="firstResponder"/>
212+
</objects>
213+
<point key="canvasLocation" x="246" y="36"/>
195214
</scene>
196215
</scenes>
197216
<resources>

ShadowView/ShadowViewExample/ExampleProgViewController.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,25 @@ class ExampleProgViewController: UIViewController {
2020
exampleShadowContainerView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
2121
exampleShadowContainerView.shadowOffset = CGSize(width: 0, height: 10)
2222
exampleShadowContainerView.shadowRadius = 20
23+
imageView.frame.size = CGSize(width: 200, height: 200)
24+
imageView.center = exampleShadowContainerView.center
2325

2426
self.view.addSubview(exampleShadowContainerView)
2527
self.exampleShadowContainerView.addSubview(imageView)
26-
imageView.center = exampleShadowContainerView.center
28+
29+
}
30+
override func viewWillAppear(_ animated: Bool) {
31+
super.viewWillAppear(animated)
32+
self.exampleShadowContainerView.updateShadow()
2733
}
2834

2935
override func viewDidLayoutSubviews() {
3036
super.viewDidLayoutSubviews()
31-
imageView.frame.size = CGSize(width: 200, height: 200)
32-
imageView.center = exampleShadowContainerView.center
37+
self.imageView.center = exampleShadowContainerView.center
3338
self.exampleShadowContainerView.updateShadow()
3439
}
3540

41+
3642
override func didReceiveMemoryWarning() {
3743
super.didReceiveMemoryWarning()
3844
// Dispose of any resources that can be recreated.

ShadowView/ShadowViewExample/ViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ViewController: UIViewController {
2424
}
2525

2626
@IBAction func blurSlider(_ sender: UISlider) {
27+
sender.isContinuous = false
2728

2829
self.exampleView.shadowRadius = CGFloat(sender.value * 50)
2930
self.otherImage.shadowRadius = CGFloat(sender.value * 50)

0 commit comments

Comments
 (0)