├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── Screenshots ├── CD1.png ├── CD2.png ├── Mountain.png ├── NoOffset.png ├── Rightoffset.png ├── largeRadius.png ├── lotus.png └── youdu.png ├── ShadowImageView.podspec ├── ShadowImageView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── ShadowImageView.xcscheme │ └── ShadowImageViewFramework.xcscheme ├── ShadowImageView ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Images │ ├── Kodaline_-_In_A_Perfect_World.jpg │ ├── cd_cover.jpg │ ├── italy-2080072_640.jpg │ ├── lotus-978659_1920.jpg │ └── prairie-679016_1920.jpg ├── Info.plist └── ViewController.swift ├── ShadowImageViewFramework ├── Info.plist └── ShadowImageViewFramework.h ├── ShadowImageViewFrameworkTests ├── Info.plist └── ShadowImageViewFrameworkTests.swift ├── ShadowImageViewTests ├── Info.plist └── ShadowImageViewTests.swift ├── ShadowImageViewUITests ├── Info.plist └── ShadowImageViewUITests.swift └── Sources ├── Extension+CIContext ├── Extension+CIContext.h ├── Extension+CIContext.m └── ShadowImageView-Bridging-Header.h └── ShadowImageView.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | *.xcworkspace 20 | !default.xcworkspace 21 | 22 | #CocoaPods 23 | Pods 24 | !Podfile 25 | !Podfile.lock 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8.3 3 | 4 | script: xcodebuild clean && xcodebuild build -project ShadowImageView.xcodeproj -scheme ShadowImageViewFramework 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 OldDonkey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShadowImageView 2 | 3 | ![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg) 4 | ![CocoaPods Support](https://img.shields.io/badge/Cocoapods-compatible-4BC51D.svg) 5 | ![Swift Version](https://img.shields.io/badge/Swift-3.0-orange.svg) 6 | ![License MIT](https://img.shields.io/badge/License-MIT-lightgrey.svg) 7 | 8 | A apple music cover picture shadow style image library 9 | 10 | ShadowImageView is a iOS 10 Apple Music style image view, help you create elegent image with shadow. 11 | 12 | 13 | ## Renderings 14 | 15 | ![ShadowOffsetRight](Screenshots/Rightoffset.png) ![Nooffset](Screenshots/NoOffset.png) ![largeRadius](Screenshots/largeRadius.png) 16 | 17 | ![lotus](Screenshots/lotus.png) ![Mountain](Screenshots/Mountain.png) ![CD1](Screenshots/CD1.png) ![CD2](Screenshots/CD2.png) 18 | 19 | 20 | ## Features 21 | 22 | - [x] Auto resizing based on content mode. 23 | - [x] Easy to change paramenters including offset, radius, alpha etc. 24 | - [x] Storyboard(Nib) support. 25 | 26 | 27 | ## TODO 28 | 29 | - [ ] Add support for UIView. 30 | - [ ] Change the way of layout, to minimize the resource usa. 31 | 32 | ## Usage 33 | 34 | 35 | ### Import 36 | 37 | #### CocoaPods 38 | You can use [CocoaPods](http://cocoapods.org/) to install `ShadowImageView` by adding it to your `Podfile`: 39 | 40 | ```ruby 41 | platform :ios, '8.0' 42 | use_frameworks! 43 | pod 'ShadowImageView' 44 | ``` 45 | 46 | #### Carthage 47 | Create a `Cartfile` that lists the framework and run `carthage update`. Follow the [instructions](https://github.com/Carthage/Carthage#if-youre-building-for-ios) to add `$(SRCROOT)/Carthage/Build/iOS/YourLibrary.framework` to an iOS project. 48 | 49 | ``` 50 | github "olddonkey/ShadowImageView" 51 | ``` 52 | #### Manually 53 | 1. Download and drop ```ShadowImageView.swift``` in your project. 54 | 2. Congratulations! 55 | 56 | ### Parameters 57 | 58 | ```swift 59 | /// Gaussian Blur radius, larger will make the back ground shadow lighter (warning: do not set it too large, 2 or 3 for most cases) 60 | @IBInspectable 61 | public var blurRadius: CGFloat 62 | 63 | /// The image view contains target image 64 | @IBInspectable 65 | public var image: UIImage 66 | 67 | /// Image's corner radius 68 | @IBInspectable 69 | public var imageCornerRaidus: CGFloat 70 | 71 | /// shadow radius offset in percentage, if you want shadow radius larger, set a postive number for this, if you want it be smaller, then set a negative number 72 | @IBInspectable 73 | public var shadowRadiusOffSetPercentage: CGFloat 74 | 75 | /// Shadow offset value on x axis, postive -> right, negative -> left 76 | @IBInspectable 77 | public var shadowOffSetByX: CGFloat 78 | 79 | 80 | /// Shadow offset value on y axis, postive -> right, negative -> left 81 | @IBInspectable 82 | public var shadowOffSetByY: CGFloat 83 | 84 | /// Shadow alpha value 85 | @IBInspectable 86 | public var shadowAlpha: CGFloat 87 | 88 | ``` 89 | 90 | If you want to add by storyboard or nib, just drap a UIView into your canvas, and change the class to ShadowImageView, you will see the change in storyboard or nib, it is @IBDesignable supported. 91 | 92 | 93 | ## Requirements 94 | 95 | - iOS 8.0+ 96 | - Swift 3+ 97 | 98 | The main development of ShadowImageView is based on Swift 3. 99 | 100 | ## Support 101 | 102 | ### Contact 103 | 104 | Follow and contact me through email: olddonkeyblog@gmail.com. If you find an issue, just [open a ticket](https://github.com/olddonkey/ShadowImageView/issues/new) on it. Pull requests are warmly welcome as well. 105 | 106 | 107 | ### License 108 | 109 | ShadowImageView is released under the MIT license. See LICENSE for details. 110 | 111 | 112 | ### Kudos 113 | 114 | Thanks to [PierrePerrin](https://github.com/PierrePerrin), his [PPMusicImageShadow](https://github.com/PierrePerrin/PPMusicImageShadow) inspires me, though the implementation is diffrent, the main idea comes from GaussianBlur. 115 | 116 | 117 | ### App using ShadowImageView 118 | 119 | 1. [优读](https://itunes.apple.com/us/app/优读-订阅收藏和碎片知识管理神器/id1175225244) 120 | 121 | ![youdu](Screenshots/youdu.png) 122 | 123 | 124 | -------------------------------------------------------------------------------- /Screenshots/CD1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/CD1.png -------------------------------------------------------------------------------- /Screenshots/CD2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/CD2.png -------------------------------------------------------------------------------- /Screenshots/Mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/Mountain.png -------------------------------------------------------------------------------- /Screenshots/NoOffset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/NoOffset.png -------------------------------------------------------------------------------- /Screenshots/Rightoffset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/Rightoffset.png -------------------------------------------------------------------------------- /Screenshots/largeRadius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/largeRadius.png -------------------------------------------------------------------------------- /Screenshots/lotus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/lotus.png -------------------------------------------------------------------------------- /Screenshots/youdu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/Screenshots/youdu.png -------------------------------------------------------------------------------- /ShadowImageView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint ShadowImageView.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "ShadowImageView" 19 | s.version = "1.6.0" 20 | s.summary = "A UIImageView smillar class that will generate iOS 10 Apple Music style shadow." 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | ShadowImageView is a iOS 10 Apple Music style image view, help you create elegent image with shadow. 29 | DESC 30 | 31 | s.homepage = "https://github.com/olddonkey/ShadowImageView" 32 | s.screenshots = "https://raw.githubusercontent.com/olddonkey/ShadowImageView/master/Screenshots/CD2.png" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | s.license = "MIT" 43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | s.author = { "olddonkey" => "olddonkeyblog@gmail.com" } 57 | # Or just: s.author = "olddonkey" 58 | # s.authors = { "olddonkey" => "olddonkeyblog@gmail.com" } 59 | # s.social_media_url = "http://twitter.com/olddonkey" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | s.platform = :ios, '8.0' 68 | # s.platform = :ios, "5.0" 69 | 70 | # When using multiple platforms 71 | # s.ios.deployment_target = "5.0" 72 | # s.osx.deployment_target = "10.7" 73 | # s.watchos.deployment_target = "2.0" 74 | # s.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | s.source = { :git => "https://github.com/olddonkey/ShadowImageView.git", :tag => "#{s.version}" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | s.source_files = "Sources", "Sources/Extension+CIContext" 95 | #s.exclude_files = "Classes/Exclude" 96 | 97 | # s.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # s.resource = "icon.png" 109 | # s.resources = "Resources/*.png" 110 | 111 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | # s.framework = "SomeFramework" 121 | s.frameworks = 'Foundation', 'UIKit' 122 | 123 | # s.library = "iconv" 124 | # s.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | # s.requires_arc = true 134 | 135 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # s.dependency "JSONKit", "~> 1.4" 137 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' } 138 | s.requires_arc = true 139 | 140 | end 141 | -------------------------------------------------------------------------------- /ShadowImageView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A21055841ED6A9B300E23378 /* Extension+CIContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A21055821ED6A9B300E23378 /* Extension+CIContext.h */; }; 11 | A21055851ED6A9B300E23378 /* Extension+CIContext.m in Sources */ = {isa = PBXBuildFile; fileRef = A21055831ED6A9B300E23378 /* Extension+CIContext.m */; }; 12 | A21055861ED6A9B300E23378 /* Extension+CIContext.m in Sources */ = {isa = PBXBuildFile; fileRef = A21055831ED6A9B300E23378 /* Extension+CIContext.m */; }; 13 | A2240DC61EB55310006FBF24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240DC51EB55310006FBF24 /* AppDelegate.swift */; }; 14 | A2240DC81EB55310006FBF24 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240DC71EB55310006FBF24 /* ViewController.swift */; }; 15 | A2240DCB1EB55310006FBF24 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A2240DC91EB55310006FBF24 /* Main.storyboard */; }; 16 | A2240DCD1EB55310006FBF24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A2240DCC1EB55310006FBF24 /* Assets.xcassets */; }; 17 | A2240DD01EB55310006FBF24 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A2240DCE1EB55310006FBF24 /* LaunchScreen.storyboard */; }; 18 | A2240DDB1EB55310006FBF24 /* ShadowImageViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240DDA1EB55310006FBF24 /* ShadowImageViewTests.swift */; }; 19 | A2240DE61EB55310006FBF24 /* ShadowImageViewUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240DE51EB55310006FBF24 /* ShadowImageViewUITests.swift */; }; 20 | A2240E091EBE5D8A006FBF24 /* ShadowImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240E081EBE5D8A006FBF24 /* ShadowImageView.swift */; }; 21 | A2240E0F1EBE5DEA006FBF24 /* cd_cover.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A2240E0A1EBE5DEA006FBF24 /* cd_cover.jpg */; }; 22 | A2240E101EBE5DEA006FBF24 /* italy-2080072_640.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A2240E0B1EBE5DEA006FBF24 /* italy-2080072_640.jpg */; }; 23 | A2240E111EBE5DEA006FBF24 /* Kodaline_-_In_A_Perfect_World.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A2240E0C1EBE5DEA006FBF24 /* Kodaline_-_In_A_Perfect_World.jpg */; }; 24 | A2240E121EBE5DEA006FBF24 /* lotus-978659_1920.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A2240E0D1EBE5DEA006FBF24 /* lotus-978659_1920.jpg */; }; 25 | A2240E131EBE5DEA006FBF24 /* prairie-679016_1920.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A2240E0E1EBE5DEA006FBF24 /* prairie-679016_1920.jpg */; }; 26 | A2240E221EBF7E84006FBF24 /* ShadowImageView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */; }; 27 | A2240E291EBF7E85006FBF24 /* ShadowImageViewFrameworkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240E281EBF7E85006FBF24 /* ShadowImageViewFrameworkTests.swift */; }; 28 | A2240E2B1EBF7E85006FBF24 /* ShadowImageViewFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = A2240E1B1EBF7E84006FBF24 /* ShadowImageViewFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | A2240E2E1EBF7E85006FBF24 /* ShadowImageView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */; }; 30 | A2240E2F1EBF7E85006FBF24 /* ShadowImageView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31 | A2240E371EBF7F00006FBF24 /* ShadowImageView.swift in Headers */ = {isa = PBXBuildFile; fileRef = A2240E081EBE5D8A006FBF24 /* ShadowImageView.swift */; }; 32 | A2240E381EBF7F07006FBF24 /* ShadowImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2240E081EBE5D8A006FBF24 /* ShadowImageView.swift */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | A2240DD71EB55310006FBF24 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = A2240DBA1EB55310006FBF24 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = A2240DC11EB55310006FBF24; 41 | remoteInfo = ShadowImageView; 42 | }; 43 | A2240DE21EB55310006FBF24 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = A2240DBA1EB55310006FBF24 /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = A2240DC11EB55310006FBF24; 48 | remoteInfo = ShadowImageView; 49 | }; 50 | A2240E231EBF7E84006FBF24 /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = A2240DBA1EB55310006FBF24 /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = A2240E181EBF7E84006FBF24; 55 | remoteInfo = ShadowImageViewFramework; 56 | }; 57 | A2240E251EBF7E85006FBF24 /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = A2240DBA1EB55310006FBF24 /* Project object */; 60 | proxyType = 1; 61 | remoteGlobalIDString = A2240DC11EB55310006FBF24; 62 | remoteInfo = ShadowImageView; 63 | }; 64 | A2240E2C1EBF7E85006FBF24 /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = A2240DBA1EB55310006FBF24 /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = A2240E181EBF7E84006FBF24; 69 | remoteInfo = ShadowImageViewFramework; 70 | }; 71 | /* End PBXContainerItemProxy section */ 72 | 73 | /* Begin PBXCopyFilesBuildPhase section */ 74 | A2240E351EBF7E85006FBF24 /* Embed Frameworks */ = { 75 | isa = PBXCopyFilesBuildPhase; 76 | buildActionMask = 2147483647; 77 | dstPath = ""; 78 | dstSubfolderSpec = 10; 79 | files = ( 80 | A2240E2F1EBF7E85006FBF24 /* ShadowImageView.framework in Embed Frameworks */, 81 | ); 82 | name = "Embed Frameworks"; 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXCopyFilesBuildPhase section */ 86 | 87 | /* Begin PBXFileReference section */ 88 | A21055821ED6A9B300E23378 /* Extension+CIContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Extension+CIContext.h"; path = "../Sources/Extension+CIContext/Extension+CIContext.h"; sourceTree = ""; }; 89 | A21055831ED6A9B300E23378 /* Extension+CIContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Extension+CIContext.m"; path = "../Sources/Extension+CIContext/Extension+CIContext.m"; sourceTree = ""; }; 90 | A2240DC21EB55310006FBF24 /* ShadowImageView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShadowImageView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | A2240DC51EB55310006FBF24 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 92 | A2240DC71EB55310006FBF24 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 93 | A2240DCA1EB55310006FBF24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 94 | A2240DCC1EB55310006FBF24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 95 | A2240DCF1EB55310006FBF24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 96 | A2240DD11EB55310006FBF24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 97 | A2240DD61EB55310006FBF24 /* ShadowImageViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShadowImageViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 98 | A2240DDA1EB55310006FBF24 /* ShadowImageViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowImageViewTests.swift; sourceTree = ""; }; 99 | A2240DDC1EB55310006FBF24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 100 | A2240DE11EB55310006FBF24 /* ShadowImageViewUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShadowImageViewUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 101 | A2240DE51EB55310006FBF24 /* ShadowImageViewUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowImageViewUITests.swift; sourceTree = ""; }; 102 | A2240DE71EB55310006FBF24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 103 | A2240E081EBE5D8A006FBF24 /* ShadowImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShadowImageView.swift; path = Sources/ShadowImageView.swift; sourceTree = SOURCE_ROOT; }; 104 | A2240E0A1EBE5DEA006FBF24 /* cd_cover.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = cd_cover.jpg; path = Images/cd_cover.jpg; sourceTree = ""; }; 105 | A2240E0B1EBE5DEA006FBF24 /* italy-2080072_640.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = "italy-2080072_640.jpg"; path = "Images/italy-2080072_640.jpg"; sourceTree = ""; }; 106 | A2240E0C1EBE5DEA006FBF24 /* Kodaline_-_In_A_Perfect_World.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = "Kodaline_-_In_A_Perfect_World.jpg"; path = "Images/Kodaline_-_In_A_Perfect_World.jpg"; sourceTree = ""; }; 107 | A2240E0D1EBE5DEA006FBF24 /* lotus-978659_1920.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = "lotus-978659_1920.jpg"; path = "Images/lotus-978659_1920.jpg"; sourceTree = ""; }; 108 | A2240E0E1EBE5DEA006FBF24 /* prairie-679016_1920.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = "prairie-679016_1920.jpg"; path = "Images/prairie-679016_1920.jpg"; sourceTree = ""; }; 109 | A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ShadowImageView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 110 | A2240E1B1EBF7E84006FBF24 /* ShadowImageViewFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShadowImageViewFramework.h; sourceTree = ""; }; 111 | A2240E1C1EBF7E84006FBF24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 112 | A2240E211EBF7E84006FBF24 /* ShadowImageViewFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShadowImageViewFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 113 | A2240E281EBF7E85006FBF24 /* ShadowImageViewFrameworkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowImageViewFrameworkTests.swift; sourceTree = ""; }; 114 | A2240E2A1EBF7E85006FBF24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 115 | /* End PBXFileReference section */ 116 | 117 | /* Begin PBXFrameworksBuildPhase section */ 118 | A2240DBF1EB55310006FBF24 /* Frameworks */ = { 119 | isa = PBXFrameworksBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | A2240E2E1EBF7E85006FBF24 /* ShadowImageView.framework in Frameworks */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | A2240DD31EB55310006FBF24 /* Frameworks */ = { 127 | isa = PBXFrameworksBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | A2240DDE1EB55310006FBF24 /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | A2240E151EBF7E84006FBF24 /* Frameworks */ = { 141 | isa = PBXFrameworksBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | A2240E1E1EBF7E84006FBF24 /* Frameworks */ = { 148 | isa = PBXFrameworksBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | A2240E221EBF7E84006FBF24 /* ShadowImageView.framework in Frameworks */, 152 | ); 153 | runOnlyForDeploymentPostprocessing = 0; 154 | }; 155 | /* End PBXFrameworksBuildPhase section */ 156 | 157 | /* Begin PBXGroup section */ 158 | A21055801ED6A98B00E23378 /* Extension+CIContext */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | A21055821ED6A9B300E23378 /* Extension+CIContext.h */, 162 | A21055831ED6A9B300E23378 /* Extension+CIContext.m */, 163 | ); 164 | name = "Extension+CIContext"; 165 | sourceTree = ""; 166 | }; 167 | A2240DB91EB55310006FBF24 = { 168 | isa = PBXGroup; 169 | children = ( 170 | A2240DC41EB55310006FBF24 /* ShadowImageView */, 171 | A2240DD91EB55310006FBF24 /* ShadowImageViewTests */, 172 | A2240DE41EB55310006FBF24 /* ShadowImageViewUITests */, 173 | A2240E1A1EBF7E84006FBF24 /* ShadowImageViewFramework */, 174 | A2240E271EBF7E85006FBF24 /* ShadowImageViewFrameworkTests */, 175 | A2240DC31EB55310006FBF24 /* Products */, 176 | ); 177 | sourceTree = ""; 178 | }; 179 | A2240DC31EB55310006FBF24 /* Products */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | A2240DC21EB55310006FBF24 /* ShadowImageView.app */, 183 | A2240DD61EB55310006FBF24 /* ShadowImageViewTests.xctest */, 184 | A2240DE11EB55310006FBF24 /* ShadowImageViewUITests.xctest */, 185 | A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */, 186 | A2240E211EBF7E84006FBF24 /* ShadowImageViewFrameworkTests.xctest */, 187 | ); 188 | name = Products; 189 | sourceTree = ""; 190 | }; 191 | A2240DC41EB55310006FBF24 /* ShadowImageView */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | A2240E051EBE5D0F006FBF24 /* Sources */, 195 | A2240E031EBD6F74006FBF24 /* images */, 196 | A2240DC51EB55310006FBF24 /* AppDelegate.swift */, 197 | A2240DC71EB55310006FBF24 /* ViewController.swift */, 198 | A2240DC91EB55310006FBF24 /* Main.storyboard */, 199 | A2240DCC1EB55310006FBF24 /* Assets.xcassets */, 200 | A2240DCE1EB55310006FBF24 /* LaunchScreen.storyboard */, 201 | A2240DD11EB55310006FBF24 /* Info.plist */, 202 | ); 203 | path = ShadowImageView; 204 | sourceTree = ""; 205 | }; 206 | A2240DD91EB55310006FBF24 /* ShadowImageViewTests */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | A2240DDA1EB55310006FBF24 /* ShadowImageViewTests.swift */, 210 | A2240DDC1EB55310006FBF24 /* Info.plist */, 211 | ); 212 | path = ShadowImageViewTests; 213 | sourceTree = ""; 214 | }; 215 | A2240DE41EB55310006FBF24 /* ShadowImageViewUITests */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | A2240DE51EB55310006FBF24 /* ShadowImageViewUITests.swift */, 219 | A2240DE71EB55310006FBF24 /* Info.plist */, 220 | ); 221 | path = ShadowImageViewUITests; 222 | sourceTree = ""; 223 | }; 224 | A2240E031EBD6F74006FBF24 /* images */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | A2240E0A1EBE5DEA006FBF24 /* cd_cover.jpg */, 228 | A2240E0B1EBE5DEA006FBF24 /* italy-2080072_640.jpg */, 229 | A2240E0C1EBE5DEA006FBF24 /* Kodaline_-_In_A_Perfect_World.jpg */, 230 | A2240E0D1EBE5DEA006FBF24 /* lotus-978659_1920.jpg */, 231 | A2240E0E1EBE5DEA006FBF24 /* prairie-679016_1920.jpg */, 232 | ); 233 | name = images; 234 | sourceTree = ""; 235 | }; 236 | A2240E051EBE5D0F006FBF24 /* Sources */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | A21055801ED6A98B00E23378 /* Extension+CIContext */, 240 | A2240E081EBE5D8A006FBF24 /* ShadowImageView.swift */, 241 | ); 242 | name = Sources; 243 | sourceTree = ""; 244 | }; 245 | A2240E1A1EBF7E84006FBF24 /* ShadowImageViewFramework */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | A2240E1B1EBF7E84006FBF24 /* ShadowImageViewFramework.h */, 249 | A2240E1C1EBF7E84006FBF24 /* Info.plist */, 250 | ); 251 | path = ShadowImageViewFramework; 252 | sourceTree = ""; 253 | }; 254 | A2240E271EBF7E85006FBF24 /* ShadowImageViewFrameworkTests */ = { 255 | isa = PBXGroup; 256 | children = ( 257 | A2240E281EBF7E85006FBF24 /* ShadowImageViewFrameworkTests.swift */, 258 | A2240E2A1EBF7E85006FBF24 /* Info.plist */, 259 | ); 260 | path = ShadowImageViewFrameworkTests; 261 | sourceTree = ""; 262 | }; 263 | /* End PBXGroup section */ 264 | 265 | /* Begin PBXHeadersBuildPhase section */ 266 | A2240E161EBF7E84006FBF24 /* Headers */ = { 267 | isa = PBXHeadersBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | A21055841ED6A9B300E23378 /* Extension+CIContext.h in Headers */, 271 | A2240E2B1EBF7E85006FBF24 /* ShadowImageViewFramework.h in Headers */, 272 | A2240E371EBF7F00006FBF24 /* ShadowImageView.swift in Headers */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXHeadersBuildPhase section */ 277 | 278 | /* Begin PBXNativeTarget section */ 279 | A2240DC11EB55310006FBF24 /* ShadowImageView */ = { 280 | isa = PBXNativeTarget; 281 | buildConfigurationList = A2240DEA1EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageView" */; 282 | buildPhases = ( 283 | A2240DBE1EB55310006FBF24 /* Sources */, 284 | A2240DBF1EB55310006FBF24 /* Frameworks */, 285 | A2240DC01EB55310006FBF24 /* Resources */, 286 | A2240E351EBF7E85006FBF24 /* Embed Frameworks */, 287 | ); 288 | buildRules = ( 289 | ); 290 | dependencies = ( 291 | A2240E2D1EBF7E85006FBF24 /* PBXTargetDependency */, 292 | ); 293 | name = ShadowImageView; 294 | productName = ShadowImageView; 295 | productReference = A2240DC21EB55310006FBF24 /* ShadowImageView.app */; 296 | productType = "com.apple.product-type.application"; 297 | }; 298 | A2240DD51EB55310006FBF24 /* ShadowImageViewTests */ = { 299 | isa = PBXNativeTarget; 300 | buildConfigurationList = A2240DED1EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewTests" */; 301 | buildPhases = ( 302 | A2240DD21EB55310006FBF24 /* Sources */, 303 | A2240DD31EB55310006FBF24 /* Frameworks */, 304 | A2240DD41EB55310006FBF24 /* Resources */, 305 | ); 306 | buildRules = ( 307 | ); 308 | dependencies = ( 309 | A2240DD81EB55310006FBF24 /* PBXTargetDependency */, 310 | ); 311 | name = ShadowImageViewTests; 312 | productName = ShadowImageViewTests; 313 | productReference = A2240DD61EB55310006FBF24 /* ShadowImageViewTests.xctest */; 314 | productType = "com.apple.product-type.bundle.unit-test"; 315 | }; 316 | A2240DE01EB55310006FBF24 /* ShadowImageViewUITests */ = { 317 | isa = PBXNativeTarget; 318 | buildConfigurationList = A2240DF01EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewUITests" */; 319 | buildPhases = ( 320 | A2240DDD1EB55310006FBF24 /* Sources */, 321 | A2240DDE1EB55310006FBF24 /* Frameworks */, 322 | A2240DDF1EB55310006FBF24 /* Resources */, 323 | ); 324 | buildRules = ( 325 | ); 326 | dependencies = ( 327 | A2240DE31EB55310006FBF24 /* PBXTargetDependency */, 328 | ); 329 | name = ShadowImageViewUITests; 330 | productName = ShadowImageViewUITests; 331 | productReference = A2240DE11EB55310006FBF24 /* ShadowImageViewUITests.xctest */; 332 | productType = "com.apple.product-type.bundle.ui-testing"; 333 | }; 334 | A2240E181EBF7E84006FBF24 /* ShadowImageViewFramework */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = A2240E341EBF7E85006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewFramework" */; 337 | buildPhases = ( 338 | A2240E141EBF7E84006FBF24 /* Sources */, 339 | A2240E151EBF7E84006FBF24 /* Frameworks */, 340 | A2240E161EBF7E84006FBF24 /* Headers */, 341 | A2240E171EBF7E84006FBF24 /* Resources */, 342 | ); 343 | buildRules = ( 344 | ); 345 | dependencies = ( 346 | ); 347 | name = ShadowImageViewFramework; 348 | productName = ShadowImageViewFramework; 349 | productReference = A2240E191EBF7E84006FBF24 /* ShadowImageView.framework */; 350 | productType = "com.apple.product-type.framework"; 351 | }; 352 | A2240E201EBF7E84006FBF24 /* ShadowImageViewFrameworkTests */ = { 353 | isa = PBXNativeTarget; 354 | buildConfigurationList = A2240E361EBF7E85006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewFrameworkTests" */; 355 | buildPhases = ( 356 | A2240E1D1EBF7E84006FBF24 /* Sources */, 357 | A2240E1E1EBF7E84006FBF24 /* Frameworks */, 358 | A2240E1F1EBF7E84006FBF24 /* Resources */, 359 | ); 360 | buildRules = ( 361 | ); 362 | dependencies = ( 363 | A2240E241EBF7E84006FBF24 /* PBXTargetDependency */, 364 | A2240E261EBF7E85006FBF24 /* PBXTargetDependency */, 365 | ); 366 | name = ShadowImageViewFrameworkTests; 367 | productName = ShadowImageViewFrameworkTests; 368 | productReference = A2240E211EBF7E84006FBF24 /* ShadowImageViewFrameworkTests.xctest */; 369 | productType = "com.apple.product-type.bundle.unit-test"; 370 | }; 371 | /* End PBXNativeTarget section */ 372 | 373 | /* Begin PBXProject section */ 374 | A2240DBA1EB55310006FBF24 /* Project object */ = { 375 | isa = PBXProject; 376 | attributes = { 377 | LastSwiftUpdateCheck = 0830; 378 | LastUpgradeCheck = 0830; 379 | ORGANIZATIONNAME = olddonkey; 380 | TargetAttributes = { 381 | A2240DC11EB55310006FBF24 = { 382 | CreatedOnToolsVersion = 8.3.2; 383 | DevelopmentTeam = KACMQNFS8H; 384 | LastSwiftMigration = 0830; 385 | ProvisioningStyle = Automatic; 386 | }; 387 | A2240DD51EB55310006FBF24 = { 388 | CreatedOnToolsVersion = 8.3.2; 389 | DevelopmentTeam = KACMQNFS8H; 390 | ProvisioningStyle = Automatic; 391 | TestTargetID = A2240DC11EB55310006FBF24; 392 | }; 393 | A2240DE01EB55310006FBF24 = { 394 | CreatedOnToolsVersion = 8.3.2; 395 | DevelopmentTeam = KACMQNFS8H; 396 | ProvisioningStyle = Automatic; 397 | TestTargetID = A2240DC11EB55310006FBF24; 398 | }; 399 | A2240E181EBF7E84006FBF24 = { 400 | CreatedOnToolsVersion = 8.3.2; 401 | DevelopmentTeam = KACMQNFS8H; 402 | LastSwiftMigration = 0830; 403 | ProvisioningStyle = Automatic; 404 | }; 405 | A2240E201EBF7E84006FBF24 = { 406 | CreatedOnToolsVersion = 8.3.2; 407 | DevelopmentTeam = KACMQNFS8H; 408 | ProvisioningStyle = Automatic; 409 | TestTargetID = A2240DC11EB55310006FBF24; 410 | }; 411 | }; 412 | }; 413 | buildConfigurationList = A2240DBD1EB55310006FBF24 /* Build configuration list for PBXProject "ShadowImageView" */; 414 | compatibilityVersion = "Xcode 3.2"; 415 | developmentRegion = English; 416 | hasScannedForEncodings = 0; 417 | knownRegions = ( 418 | en, 419 | Base, 420 | ); 421 | mainGroup = A2240DB91EB55310006FBF24; 422 | productRefGroup = A2240DC31EB55310006FBF24 /* Products */; 423 | projectDirPath = ""; 424 | projectRoot = ""; 425 | targets = ( 426 | A2240DC11EB55310006FBF24 /* ShadowImageView */, 427 | A2240DD51EB55310006FBF24 /* ShadowImageViewTests */, 428 | A2240DE01EB55310006FBF24 /* ShadowImageViewUITests */, 429 | A2240E181EBF7E84006FBF24 /* ShadowImageViewFramework */, 430 | A2240E201EBF7E84006FBF24 /* ShadowImageViewFrameworkTests */, 431 | ); 432 | }; 433 | /* End PBXProject section */ 434 | 435 | /* Begin PBXResourcesBuildPhase section */ 436 | A2240DC01EB55310006FBF24 /* Resources */ = { 437 | isa = PBXResourcesBuildPhase; 438 | buildActionMask = 2147483647; 439 | files = ( 440 | A2240E0F1EBE5DEA006FBF24 /* cd_cover.jpg in Resources */, 441 | A2240DD01EB55310006FBF24 /* LaunchScreen.storyboard in Resources */, 442 | A2240DCD1EB55310006FBF24 /* Assets.xcassets in Resources */, 443 | A2240DCB1EB55310006FBF24 /* Main.storyboard in Resources */, 444 | A2240E111EBE5DEA006FBF24 /* Kodaline_-_In_A_Perfect_World.jpg in Resources */, 445 | A2240E101EBE5DEA006FBF24 /* italy-2080072_640.jpg in Resources */, 446 | A2240E121EBE5DEA006FBF24 /* lotus-978659_1920.jpg in Resources */, 447 | A2240E131EBE5DEA006FBF24 /* prairie-679016_1920.jpg in Resources */, 448 | ); 449 | runOnlyForDeploymentPostprocessing = 0; 450 | }; 451 | A2240DD41EB55310006FBF24 /* Resources */ = { 452 | isa = PBXResourcesBuildPhase; 453 | buildActionMask = 2147483647; 454 | files = ( 455 | ); 456 | runOnlyForDeploymentPostprocessing = 0; 457 | }; 458 | A2240DDF1EB55310006FBF24 /* Resources */ = { 459 | isa = PBXResourcesBuildPhase; 460 | buildActionMask = 2147483647; 461 | files = ( 462 | ); 463 | runOnlyForDeploymentPostprocessing = 0; 464 | }; 465 | A2240E171EBF7E84006FBF24 /* Resources */ = { 466 | isa = PBXResourcesBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | ); 470 | runOnlyForDeploymentPostprocessing = 0; 471 | }; 472 | A2240E1F1EBF7E84006FBF24 /* Resources */ = { 473 | isa = PBXResourcesBuildPhase; 474 | buildActionMask = 2147483647; 475 | files = ( 476 | ); 477 | runOnlyForDeploymentPostprocessing = 0; 478 | }; 479 | /* End PBXResourcesBuildPhase section */ 480 | 481 | /* Begin PBXSourcesBuildPhase section */ 482 | A2240DBE1EB55310006FBF24 /* Sources */ = { 483 | isa = PBXSourcesBuildPhase; 484 | buildActionMask = 2147483647; 485 | files = ( 486 | A2240E091EBE5D8A006FBF24 /* ShadowImageView.swift in Sources */, 487 | A21055851ED6A9B300E23378 /* Extension+CIContext.m in Sources */, 488 | A2240DC81EB55310006FBF24 /* ViewController.swift in Sources */, 489 | A2240DC61EB55310006FBF24 /* AppDelegate.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | A2240DD21EB55310006FBF24 /* Sources */ = { 494 | isa = PBXSourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | A2240DDB1EB55310006FBF24 /* ShadowImageViewTests.swift in Sources */, 498 | ); 499 | runOnlyForDeploymentPostprocessing = 0; 500 | }; 501 | A2240DDD1EB55310006FBF24 /* Sources */ = { 502 | isa = PBXSourcesBuildPhase; 503 | buildActionMask = 2147483647; 504 | files = ( 505 | A2240DE61EB55310006FBF24 /* ShadowImageViewUITests.swift in Sources */, 506 | ); 507 | runOnlyForDeploymentPostprocessing = 0; 508 | }; 509 | A2240E141EBF7E84006FBF24 /* Sources */ = { 510 | isa = PBXSourcesBuildPhase; 511 | buildActionMask = 2147483647; 512 | files = ( 513 | A2240E381EBF7F07006FBF24 /* ShadowImageView.swift in Sources */, 514 | A21055861ED6A9B300E23378 /* Extension+CIContext.m in Sources */, 515 | ); 516 | runOnlyForDeploymentPostprocessing = 0; 517 | }; 518 | A2240E1D1EBF7E84006FBF24 /* Sources */ = { 519 | isa = PBXSourcesBuildPhase; 520 | buildActionMask = 2147483647; 521 | files = ( 522 | A2240E291EBF7E85006FBF24 /* ShadowImageViewFrameworkTests.swift in Sources */, 523 | ); 524 | runOnlyForDeploymentPostprocessing = 0; 525 | }; 526 | /* End PBXSourcesBuildPhase section */ 527 | 528 | /* Begin PBXTargetDependency section */ 529 | A2240DD81EB55310006FBF24 /* PBXTargetDependency */ = { 530 | isa = PBXTargetDependency; 531 | target = A2240DC11EB55310006FBF24 /* ShadowImageView */; 532 | targetProxy = A2240DD71EB55310006FBF24 /* PBXContainerItemProxy */; 533 | }; 534 | A2240DE31EB55310006FBF24 /* PBXTargetDependency */ = { 535 | isa = PBXTargetDependency; 536 | target = A2240DC11EB55310006FBF24 /* ShadowImageView */; 537 | targetProxy = A2240DE21EB55310006FBF24 /* PBXContainerItemProxy */; 538 | }; 539 | A2240E241EBF7E84006FBF24 /* PBXTargetDependency */ = { 540 | isa = PBXTargetDependency; 541 | target = A2240E181EBF7E84006FBF24 /* ShadowImageViewFramework */; 542 | targetProxy = A2240E231EBF7E84006FBF24 /* PBXContainerItemProxy */; 543 | }; 544 | A2240E261EBF7E85006FBF24 /* PBXTargetDependency */ = { 545 | isa = PBXTargetDependency; 546 | target = A2240DC11EB55310006FBF24 /* ShadowImageView */; 547 | targetProxy = A2240E251EBF7E85006FBF24 /* PBXContainerItemProxy */; 548 | }; 549 | A2240E2D1EBF7E85006FBF24 /* PBXTargetDependency */ = { 550 | isa = PBXTargetDependency; 551 | target = A2240E181EBF7E84006FBF24 /* ShadowImageViewFramework */; 552 | targetProxy = A2240E2C1EBF7E85006FBF24 /* PBXContainerItemProxy */; 553 | }; 554 | /* End PBXTargetDependency section */ 555 | 556 | /* Begin PBXVariantGroup section */ 557 | A2240DC91EB55310006FBF24 /* Main.storyboard */ = { 558 | isa = PBXVariantGroup; 559 | children = ( 560 | A2240DCA1EB55310006FBF24 /* Base */, 561 | ); 562 | name = Main.storyboard; 563 | sourceTree = ""; 564 | }; 565 | A2240DCE1EB55310006FBF24 /* LaunchScreen.storyboard */ = { 566 | isa = PBXVariantGroup; 567 | children = ( 568 | A2240DCF1EB55310006FBF24 /* Base */, 569 | ); 570 | name = LaunchScreen.storyboard; 571 | sourceTree = ""; 572 | }; 573 | /* End PBXVariantGroup section */ 574 | 575 | /* Begin XCBuildConfiguration section */ 576 | A2240DE81EB55310006FBF24 /* Debug */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | ALWAYS_SEARCH_USER_PATHS = NO; 580 | CLANG_ANALYZER_NONNULL = YES; 581 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 582 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 583 | CLANG_CXX_LIBRARY = "libc++"; 584 | CLANG_ENABLE_MODULES = YES; 585 | CLANG_ENABLE_OBJC_ARC = YES; 586 | CLANG_WARN_BOOL_CONVERSION = YES; 587 | CLANG_WARN_CONSTANT_CONVERSION = YES; 588 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 589 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 590 | CLANG_WARN_EMPTY_BODY = YES; 591 | CLANG_WARN_ENUM_CONVERSION = YES; 592 | CLANG_WARN_INFINITE_RECURSION = YES; 593 | CLANG_WARN_INT_CONVERSION = YES; 594 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 595 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 596 | CLANG_WARN_UNREACHABLE_CODE = YES; 597 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 598 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 599 | COPY_PHASE_STRIP = NO; 600 | DEBUG_INFORMATION_FORMAT = dwarf; 601 | ENABLE_STRICT_OBJC_MSGSEND = YES; 602 | ENABLE_TESTABILITY = YES; 603 | GCC_C_LANGUAGE_STANDARD = gnu99; 604 | GCC_DYNAMIC_NO_PIC = NO; 605 | GCC_NO_COMMON_BLOCKS = YES; 606 | GCC_OPTIMIZATION_LEVEL = 0; 607 | GCC_PREPROCESSOR_DEFINITIONS = ( 608 | "DEBUG=1", 609 | "$(inherited)", 610 | ); 611 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 612 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 613 | GCC_WARN_UNDECLARED_SELECTOR = YES; 614 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 615 | GCC_WARN_UNUSED_FUNCTION = YES; 616 | GCC_WARN_UNUSED_VARIABLE = YES; 617 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 618 | MTL_ENABLE_DEBUG_INFO = YES; 619 | ONLY_ACTIVE_ARCH = YES; 620 | SDKROOT = iphoneos; 621 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 622 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 623 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 624 | TARGETED_DEVICE_FAMILY = "1,2"; 625 | }; 626 | name = Debug; 627 | }; 628 | A2240DE91EB55310006FBF24 /* Release */ = { 629 | isa = XCBuildConfiguration; 630 | buildSettings = { 631 | ALWAYS_SEARCH_USER_PATHS = NO; 632 | CLANG_ANALYZER_NONNULL = YES; 633 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 634 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 635 | CLANG_CXX_LIBRARY = "libc++"; 636 | CLANG_ENABLE_MODULES = YES; 637 | CLANG_ENABLE_OBJC_ARC = YES; 638 | CLANG_WARN_BOOL_CONVERSION = YES; 639 | CLANG_WARN_CONSTANT_CONVERSION = YES; 640 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 641 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 642 | CLANG_WARN_EMPTY_BODY = YES; 643 | CLANG_WARN_ENUM_CONVERSION = YES; 644 | CLANG_WARN_INFINITE_RECURSION = YES; 645 | CLANG_WARN_INT_CONVERSION = YES; 646 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 647 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 648 | CLANG_WARN_UNREACHABLE_CODE = YES; 649 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 650 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 651 | COPY_PHASE_STRIP = NO; 652 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 653 | ENABLE_NS_ASSERTIONS = NO; 654 | ENABLE_STRICT_OBJC_MSGSEND = YES; 655 | GCC_C_LANGUAGE_STANDARD = gnu99; 656 | GCC_NO_COMMON_BLOCKS = YES; 657 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 658 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 659 | GCC_WARN_UNDECLARED_SELECTOR = YES; 660 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 661 | GCC_WARN_UNUSED_FUNCTION = YES; 662 | GCC_WARN_UNUSED_VARIABLE = YES; 663 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 664 | MTL_ENABLE_DEBUG_INFO = NO; 665 | SDKROOT = iphoneos; 666 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 667 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 668 | TARGETED_DEVICE_FAMILY = "1,2"; 669 | VALIDATE_PRODUCT = YES; 670 | }; 671 | name = Release; 672 | }; 673 | A2240DEB1EB55310006FBF24 /* Debug */ = { 674 | isa = XCBuildConfiguration; 675 | buildSettings = { 676 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 677 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 678 | CLANG_ENABLE_MODULES = YES; 679 | DEVELOPMENT_TEAM = KACMQNFS8H; 680 | INFOPLIST_FILE = ShadowImageView/Info.plist; 681 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 682 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 683 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageView; 684 | PRODUCT_NAME = "$(TARGET_NAME)"; 685 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 686 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 687 | SWIFT_VERSION = 3.0; 688 | }; 689 | name = Debug; 690 | }; 691 | A2240DEC1EB55310006FBF24 /* Release */ = { 692 | isa = XCBuildConfiguration; 693 | buildSettings = { 694 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 695 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 696 | CLANG_ENABLE_MODULES = YES; 697 | DEVELOPMENT_TEAM = KACMQNFS8H; 698 | INFOPLIST_FILE = ShadowImageView/Info.plist; 699 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 700 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 701 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageView; 702 | PRODUCT_NAME = "$(TARGET_NAME)"; 703 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 704 | SWIFT_VERSION = 3.0; 705 | }; 706 | name = Release; 707 | }; 708 | A2240DEE1EB55310006FBF24 /* Debug */ = { 709 | isa = XCBuildConfiguration; 710 | buildSettings = { 711 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 712 | BUNDLE_LOADER = "$(TEST_HOST)"; 713 | DEVELOPMENT_TEAM = KACMQNFS8H; 714 | INFOPLIST_FILE = ShadowImageViewTests/Info.plist; 715 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 716 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewTests; 717 | PRODUCT_NAME = "$(TARGET_NAME)"; 718 | SWIFT_VERSION = 3.0; 719 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowImageView.app/ShadowImageView"; 720 | }; 721 | name = Debug; 722 | }; 723 | A2240DEF1EB55310006FBF24 /* Release */ = { 724 | isa = XCBuildConfiguration; 725 | buildSettings = { 726 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 727 | BUNDLE_LOADER = "$(TEST_HOST)"; 728 | DEVELOPMENT_TEAM = KACMQNFS8H; 729 | INFOPLIST_FILE = ShadowImageViewTests/Info.plist; 730 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 731 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewTests; 732 | PRODUCT_NAME = "$(TARGET_NAME)"; 733 | SWIFT_VERSION = 3.0; 734 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowImageView.app/ShadowImageView"; 735 | }; 736 | name = Release; 737 | }; 738 | A2240DF11EB55310006FBF24 /* Debug */ = { 739 | isa = XCBuildConfiguration; 740 | buildSettings = { 741 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 742 | DEVELOPMENT_TEAM = KACMQNFS8H; 743 | INFOPLIST_FILE = ShadowImageViewUITests/Info.plist; 744 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 745 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewUITests; 746 | PRODUCT_NAME = "$(TARGET_NAME)"; 747 | SWIFT_VERSION = 3.0; 748 | TEST_TARGET_NAME = ShadowImageView; 749 | }; 750 | name = Debug; 751 | }; 752 | A2240DF21EB55310006FBF24 /* Release */ = { 753 | isa = XCBuildConfiguration; 754 | buildSettings = { 755 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 756 | DEVELOPMENT_TEAM = KACMQNFS8H; 757 | INFOPLIST_FILE = ShadowImageViewUITests/Info.plist; 758 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 759 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewUITests; 760 | PRODUCT_NAME = "$(TARGET_NAME)"; 761 | SWIFT_VERSION = 3.0; 762 | TEST_TARGET_NAME = ShadowImageView; 763 | }; 764 | name = Release; 765 | }; 766 | A2240E301EBF7E85006FBF24 /* Debug */ = { 767 | isa = XCBuildConfiguration; 768 | buildSettings = { 769 | CLANG_ENABLE_MODULES = YES; 770 | CODE_SIGN_IDENTITY = ""; 771 | CURRENT_PROJECT_VERSION = 1; 772 | DEFINES_MODULE = YES; 773 | DEVELOPMENT_TEAM = KACMQNFS8H; 774 | DYLIB_COMPATIBILITY_VERSION = 1; 775 | DYLIB_CURRENT_VERSION = 1; 776 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 777 | INFOPLIST_FILE = ShadowImageViewFramework/Info.plist; 778 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 779 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 780 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 781 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewFramework; 782 | PRODUCT_NAME = ShadowImageView; 783 | SKIP_INSTALL = YES; 784 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 785 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 786 | SWIFT_VERSION = 3.0; 787 | VERSIONING_SYSTEM = "apple-generic"; 788 | VERSION_INFO_PREFIX = ""; 789 | }; 790 | name = Debug; 791 | }; 792 | A2240E311EBF7E85006FBF24 /* Release */ = { 793 | isa = XCBuildConfiguration; 794 | buildSettings = { 795 | CLANG_ENABLE_MODULES = YES; 796 | CODE_SIGN_IDENTITY = ""; 797 | CURRENT_PROJECT_VERSION = 1; 798 | DEFINES_MODULE = YES; 799 | DEVELOPMENT_TEAM = KACMQNFS8H; 800 | DYLIB_COMPATIBILITY_VERSION = 1; 801 | DYLIB_CURRENT_VERSION = 1; 802 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 803 | INFOPLIST_FILE = ShadowImageViewFramework/Info.plist; 804 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 805 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 806 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 807 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewFramework; 808 | PRODUCT_NAME = ShadowImageView; 809 | SKIP_INSTALL = YES; 810 | SWIFT_OBJC_BRIDGING_HEADER = "Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h"; 811 | SWIFT_VERSION = 3.0; 812 | VERSIONING_SYSTEM = "apple-generic"; 813 | VERSION_INFO_PREFIX = ""; 814 | }; 815 | name = Release; 816 | }; 817 | A2240E321EBF7E85006FBF24 /* Debug */ = { 818 | isa = XCBuildConfiguration; 819 | buildSettings = { 820 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 821 | DEVELOPMENT_TEAM = KACMQNFS8H; 822 | INFOPLIST_FILE = ShadowImageViewFrameworkTests/Info.plist; 823 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 824 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewFrameworkTests; 825 | PRODUCT_NAME = "$(TARGET_NAME)"; 826 | SWIFT_VERSION = 3.0; 827 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowImageView.app/ShadowImageView"; 828 | }; 829 | name = Debug; 830 | }; 831 | A2240E331EBF7E85006FBF24 /* Release */ = { 832 | isa = XCBuildConfiguration; 833 | buildSettings = { 834 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 835 | DEVELOPMENT_TEAM = KACMQNFS8H; 836 | INFOPLIST_FILE = ShadowImageViewFrameworkTests/Info.plist; 837 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 838 | PRODUCT_BUNDLE_IDENTIFIER = com.olddonkey.ShadowImageViewFrameworkTests; 839 | PRODUCT_NAME = "$(TARGET_NAME)"; 840 | SWIFT_VERSION = 3.0; 841 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShadowImageView.app/ShadowImageView"; 842 | }; 843 | name = Release; 844 | }; 845 | /* End XCBuildConfiguration section */ 846 | 847 | /* Begin XCConfigurationList section */ 848 | A2240DBD1EB55310006FBF24 /* Build configuration list for PBXProject "ShadowImageView" */ = { 849 | isa = XCConfigurationList; 850 | buildConfigurations = ( 851 | A2240DE81EB55310006FBF24 /* Debug */, 852 | A2240DE91EB55310006FBF24 /* Release */, 853 | ); 854 | defaultConfigurationIsVisible = 0; 855 | defaultConfigurationName = Release; 856 | }; 857 | A2240DEA1EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageView" */ = { 858 | isa = XCConfigurationList; 859 | buildConfigurations = ( 860 | A2240DEB1EB55310006FBF24 /* Debug */, 861 | A2240DEC1EB55310006FBF24 /* Release */, 862 | ); 863 | defaultConfigurationIsVisible = 0; 864 | defaultConfigurationName = Release; 865 | }; 866 | A2240DED1EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewTests" */ = { 867 | isa = XCConfigurationList; 868 | buildConfigurations = ( 869 | A2240DEE1EB55310006FBF24 /* Debug */, 870 | A2240DEF1EB55310006FBF24 /* Release */, 871 | ); 872 | defaultConfigurationIsVisible = 0; 873 | defaultConfigurationName = Release; 874 | }; 875 | A2240DF01EB55310006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewUITests" */ = { 876 | isa = XCConfigurationList; 877 | buildConfigurations = ( 878 | A2240DF11EB55310006FBF24 /* Debug */, 879 | A2240DF21EB55310006FBF24 /* Release */, 880 | ); 881 | defaultConfigurationIsVisible = 0; 882 | defaultConfigurationName = Release; 883 | }; 884 | A2240E341EBF7E85006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewFramework" */ = { 885 | isa = XCConfigurationList; 886 | buildConfigurations = ( 887 | A2240E301EBF7E85006FBF24 /* Debug */, 888 | A2240E311EBF7E85006FBF24 /* Release */, 889 | ); 890 | defaultConfigurationIsVisible = 0; 891 | defaultConfigurationName = Release; 892 | }; 893 | A2240E361EBF7E85006FBF24 /* Build configuration list for PBXNativeTarget "ShadowImageViewFrameworkTests" */ = { 894 | isa = XCConfigurationList; 895 | buildConfigurations = ( 896 | A2240E321EBF7E85006FBF24 /* Debug */, 897 | A2240E331EBF7E85006FBF24 /* Release */, 898 | ); 899 | defaultConfigurationIsVisible = 0; 900 | defaultConfigurationName = Release; 901 | }; 902 | /* End XCConfigurationList section */ 903 | }; 904 | rootObject = A2240DBA1EB55310006FBF24 /* Project object */; 905 | } 906 | -------------------------------------------------------------------------------- /ShadowImageView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ShadowImageView.xcodeproj/xcshareddata/xcschemes/ShadowImageView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 71 | 72 | 73 | 74 | 84 | 86 | 92 | 93 | 94 | 95 | 96 | 97 | 103 | 105 | 111 | 112 | 113 | 114 | 116 | 117 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /ShadowImageView.xcodeproj/xcshareddata/xcschemes/ShadowImageViewFramework.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ShadowImageView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ShadowImageView 4 | // 5 | // Created by olddonkey on 2017/4/29. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /ShadowImageView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /ShadowImageView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /ShadowImageView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /ShadowImageView/Images/Kodaline_-_In_A_Perfect_World.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/ShadowImageView/Images/Kodaline_-_In_A_Perfect_World.jpg -------------------------------------------------------------------------------- /ShadowImageView/Images/cd_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/ShadowImageView/Images/cd_cover.jpg -------------------------------------------------------------------------------- /ShadowImageView/Images/italy-2080072_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/ShadowImageView/Images/italy-2080072_640.jpg -------------------------------------------------------------------------------- /ShadowImageView/Images/lotus-978659_1920.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/ShadowImageView/Images/lotus-978659_1920.jpg -------------------------------------------------------------------------------- /ShadowImageView/Images/prairie-679016_1920.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olddonkey/ShadowImageView/d36e90471455c072be944cf84e5d22836b71386d/ShadowImageView/Images/prairie-679016_1920.jpg -------------------------------------------------------------------------------- /ShadowImageView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ShadowImageView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ShadowImageView 4 | // 5 | // Created by olddonkey on 2017/4/29. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak var shadowImage: ShadowImageView! 14 | @IBOutlet weak var shadowAlphaSlider: UISlider! 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do any additional setup after loading the view, typically from a nib. 18 | } 19 | 20 | @IBAction func sliderDidChange(_ sender: UISlider) { 21 | shadowImage.shadowAlpha = CGFloat(sender.value) 22 | } 23 | 24 | override func didReceiveMemoryWarning() { 25 | super.didReceiveMemoryWarning() 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /ShadowImageViewFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ShadowImageViewFramework/ShadowImageViewFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShadowImageViewFramework.h 3 | // ShadowImageViewFramework 4 | // 5 | // Created by olddonkey on 2017/5/7. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ShadowImageViewFramework. 12 | FOUNDATION_EXPORT double ShadowImageViewFrameworkVersionNumber; 13 | 14 | //! Project version string for ShadowImageViewFramework. 15 | FOUNDATION_EXPORT const unsigned char ShadowImageViewFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /ShadowImageViewFrameworkTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ShadowImageViewFrameworkTests/ShadowImageViewFrameworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShadowImageViewFrameworkTests.swift 3 | // ShadowImageViewFrameworkTests 4 | // 5 | // Created by olddonkey on 2017/5/7. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ShadowImageViewFramework 11 | 12 | class ShadowImageViewFrameworkTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ShadowImageViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ShadowImageViewTests/ShadowImageViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShadowImageViewTests.swift 3 | // ShadowImageViewTests 4 | // 5 | // Created by olddonkey on 2017/4/29. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ShadowImageView 11 | 12 | class ShadowImageViewTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ShadowImageViewUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ShadowImageViewUITests/ShadowImageViewUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShadowImageViewUITests.swift 3 | // ShadowImageViewUITests 4 | // 5 | // Created by olddonkey on 2017/4/29. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ShadowImageViewUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Sources/Extension+CIContext/Extension+CIContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // Extension+CIContext.h 3 | // ShadowImageView 4 | // 5 | // Created by Jinkey on 2017/5/20. 6 | // Copyright © 2017年 Jinkey. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CIContext (bridging) 12 | + (CIContext * _Nonnull)bridging_contextWithOptions:(nullable NSDictionary *)options 13 | NS_AVAILABLE(10_4,5_0); 14 | @end 15 | -------------------------------------------------------------------------------- /Sources/Extension+CIContext/Extension+CIContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // Extension+CIContext.m 3 | // ShadowImageView 4 | // 5 | // Created by Jinkey on 2017/5/20. 6 | // Copyright © 2017年 Jinkey. All rights reserved. 7 | // 8 | 9 | #import "Extension+CIContext.h" 10 | 11 | @implementation CIContext (bridging) 12 | + (CIContext *)bridging_contextWithOptions:(NSDictionary *)options { 13 | return [CIContext contextWithOptions:options]; 14 | } 15 | @end 16 | 17 | 18 | -------------------------------------------------------------------------------- /Sources/Extension+CIContext/ShadowImageView-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | #import "Extension+CIContext.h" 5 | -------------------------------------------------------------------------------- /Sources/ShadowImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShadowImageView.swift 3 | // ShadowImageView 4 | // 5 | // Created by olddonkey on 2017/4/29. 6 | // Copyright © 2017年 olddonkey. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreGraphics 11 | 12 | @IBDesignable 13 | public class ShadowImageView: UIView { 14 | 15 | private var imageView = UIImageView() 16 | private var blurredImageView = UIImageView() 17 | 18 | 19 | /// Gaussian Blur radius, larger will make the back ground shadow lighter (warning: do not set it too large, 2 or 3 for most cases) 20 | @IBInspectable 21 | public var blurRadius: CGFloat = 3 { 22 | didSet { 23 | layoutShadow() 24 | } 25 | } 26 | 27 | /// The image view contains target image 28 | @IBInspectable 29 | public var image: UIImage? { 30 | set { 31 | DispatchQueue.main.async { 32 | self.imageView.image = newValue 33 | self.layoutShadow() 34 | } 35 | } 36 | get { 37 | return self.imageView.image 38 | } 39 | } 40 | 41 | /// Image's corner radius 42 | @IBInspectable 43 | public var imageCornerRaidus: CGFloat = 0 { 44 | didSet { 45 | imageView.layer.cornerRadius = imageCornerRaidus 46 | imageView.layer.masksToBounds = true 47 | } 48 | } 49 | 50 | /// shadow radius offset in percentage, if you want shadow radius larger, set a postive number for this, if you want it be smaller, then set a negative number 51 | @IBInspectable 52 | public var shadowRadiusOffSetPercentage: CGFloat = 0 { 53 | didSet { 54 | layoutShadow() 55 | } 56 | } 57 | 58 | /// Shadow offset value on x axis, postive -> right, negative -> left 59 | @IBInspectable 60 | public var shadowOffSetByX: CGFloat = 0 { 61 | didSet { 62 | layoutShadow() 63 | } 64 | } 65 | 66 | 67 | /// Shadow offset value on y axis, postive -> right, negative -> left 68 | @IBInspectable 69 | public var shadowOffSetByY: CGFloat = 0 { 70 | didSet { 71 | layoutShadow() 72 | } 73 | } 74 | 75 | 76 | /// Shadow alpha value 77 | @IBInspectable 78 | public var shadowAlpha: CGFloat = 1 { 79 | didSet { 80 | blurredImageView.alpha = shadowAlpha 81 | } 82 | } 83 | 84 | override public var contentMode: UIViewContentMode { 85 | didSet{ 86 | layoutShadow() 87 | } 88 | } 89 | 90 | override public func layoutSubviews() { 91 | super.layoutSubviews() 92 | layoutShadow() 93 | } 94 | 95 | /// Generate the background color and set it to a image view. 96 | private func generateBlurBackground() { 97 | guard let image = image else{ 98 | return 99 | } 100 | let realImageSize = getRealImageSize(image) 101 | DispatchQueue.global(qos: .userInteractive).async { [weak self] in 102 | guard let weakself = self else { 103 | return 104 | } 105 | // Create a containerView to hold the image should apply gaussian blur. 106 | let containerLayer = CALayer() 107 | containerLayer.frame = CGRect(origin: .zero, size: realImageSize.scaled(by: 1.4)) 108 | containerLayer.backgroundColor = UIColor.clear.cgColor 109 | let blurImageLayer = CALayer() 110 | blurImageLayer.frame = CGRect(origin: CGPoint.init(x: realImageSize.width*0.2, y: realImageSize.height*0.2), size: realImageSize) 111 | blurImageLayer.contents = image.cgImage 112 | blurImageLayer.cornerRadius = weakself.imageCornerRaidus 113 | blurImageLayer.masksToBounds = true 114 | containerLayer.addSublayer(blurImageLayer) 115 | 116 | var containerImage = UIImage() 117 | // Get the UIImage from a UIView. 118 | if containerLayer.frame.size != CGSize.zero { 119 | containerImage = UIImage(layer: containerLayer) 120 | }else { 121 | containerImage = UIImage() 122 | } 123 | 124 | guard let resizedContainerImage = containerImage.resized(withPercentage: 0.2), 125 | let ciimage = CIImage(image: resizedContainerImage), 126 | let blurredImage = weakself.applyBlur(ciimage: ciimage) else { 127 | return 128 | } 129 | 130 | DispatchQueue.main.async { 131 | self?.blurredImageView.image = blurredImage 132 | } 133 | } 134 | } 135 | 136 | /// Apply Gaussian Blur to a ciimage, and return a UIImage 137 | /// 138 | /// - Parameter ciimage: the imput CIImage 139 | /// - Returns: output UIImage 140 | private func applyBlur(ciimage: CIImage) -> UIImage? { 141 | 142 | if let filter = CIFilter(name: "CIGaussianBlur") { 143 | filter.setValue(ciimage, forKey: kCIInputImageKey) 144 | filter.setValue(blurRadius, forKeyPath: kCIInputRadiusKey) 145 | 146 | // Due to a iOS 8 bug, we need to bridging CIContext from OC to avoid crashing 147 | let context = CIContext.bridging_context(options: nil) 148 | if let output = filter.outputImage, let cgimage = context.createCGImage(output, from: ciimage.extent) { 149 | return UIImage(cgImage: cgimage) 150 | } 151 | } 152 | return nil 153 | } 154 | 155 | /// Due to scaleAspectFit, need to calculate the real size of the image and set the corner radius 156 | /// 157 | /// - Parameter from: input image 158 | /// - Returns: the real size of the image 159 | func getRealImageSize(_ from: UIImage) -> CGSize { 160 | if contentMode == .scaleAspectFit { 161 | let scale = min(bounds.size.width / from.size.width, bounds.size.height / from.size.height) 162 | return from.size.scaled(by: scale) 163 | } else { 164 | return from.size 165 | } 166 | } 167 | 168 | override public func willMove(toSuperview newSuperview: UIView?) { 169 | super.willMove(toSuperview: newSuperview) 170 | backgroundColor = .clear 171 | if newSuperview != nil { 172 | layoutImageView() 173 | } 174 | } 175 | 176 | private func layoutShadow() { 177 | 178 | DispatchQueue.main.async { 179 | self.generateBlurBackground() 180 | guard let image = self.image else { 181 | return 182 | } 183 | 184 | let realImageSize = self.getRealImageSize(image) 185 | 186 | self.imageView.frame = CGRect(origin: .zero, size: realImageSize) 187 | self.imageView.center = CGPoint(x: self.bounds.width/2, y: self.bounds.height/2) 188 | 189 | let newSize = realImageSize.scaled(by: 1.4 * (1 + self.shadowRadiusOffSetPercentage/100)) 190 | 191 | self.blurredImageView.frame = CGRect(origin: .zero, size: newSize) 192 | self.blurredImageView.center = CGPoint(x: self.bounds.width/2 + self.shadowOffSetByX, y: self.bounds.height/2 + self.shadowOffSetByY) 193 | self.blurredImageView.contentMode = self.contentMode 194 | self.blurredImageView.alpha = self.shadowAlpha 195 | } 196 | 197 | } 198 | 199 | private func layoutImageView() { 200 | imageView.image = image 201 | imageView.frame = bounds 202 | 203 | imageView.layer.cornerRadius = imageCornerRaidus 204 | imageView.layer.masksToBounds = true 205 | imageView.contentMode = contentMode 206 | addSubview(imageView) 207 | addSubview(blurredImageView) 208 | sendSubview(toBack: blurredImageView) 209 | } 210 | 211 | } 212 | 213 | private extension CGSize { 214 | 215 | /// Generates a new size that is this size scaled by a cerntain percentage 216 | /// 217 | /// - Parameter percentage: the percentage to scale to 218 | /// - Returns: a new CGSize instance by scaling self by the given percentage 219 | func scaled(by percentage: CGFloat) -> CGSize { 220 | return CGSize(width: width * percentage, height: height * percentage) 221 | } 222 | 223 | } 224 | 225 | private extension UIImage { 226 | 227 | /// Resize the image to a centain percentage 228 | /// 229 | /// - Parameter percentage: Percentage value 230 | /// - Returns: UIImage(Optional) 231 | func resized(withPercentage percentage: CGFloat) -> UIImage? { 232 | let canvasSize = size.scaled(by: percentage) 233 | UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale) 234 | defer { UIGraphicsEndImageContext() } 235 | draw(in: CGRect(origin: .zero, size: canvasSize)) 236 | return UIGraphicsGetImageFromCurrentImageContext() 237 | } 238 | 239 | /// Method to create a UIImage from CALayer 240 | /// 241 | /// - Parameter layer: input Layer 242 | convenience init(layer: CALayer) { 243 | UIGraphicsBeginImageContext(layer.frame.size) 244 | layer.render(in: UIGraphicsGetCurrentContext()!) 245 | let image = UIGraphicsGetImageFromCurrentImageContext() 246 | UIGraphicsEndImageContext() 247 | if let cgImage = image?.cgImage { 248 | self.init(cgImage: cgImage) 249 | } else { 250 | self.init() 251 | } 252 | } 253 | } 254 | --------------------------------------------------------------------------------