├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── PulsingHalo.podspec ├── PulsingHalo ├── Info.plist ├── PulsingHalo.h ├── PulsingHaloLayer.h └── PulsingHaloLayer.m ├── PulsingHaloDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── PulsingHalo.xcscheme ├── PulsingHaloDemo ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-Small@2x.png │ │ └── Icon-Small@3x.png │ ├── Contents.json │ ├── Image.imageset │ │ ├── Contents.json │ │ └── IPhone_5s.png │ └── bluetooth_book.imageset │ │ ├── Contents.json │ │ └── bluetooth_book.pdf ├── Launch Screen.storyboard ├── PulsingHaloDemo-Info.plist ├── PulsingHaloDemo-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── PulsingHaloDemoTests ├── PulsingHaloDemoTests-Info.plist ├── PulsingHaloDemoTests.m └── en.lproj │ └── InfoPlist.strings ├── README.md └── demo_.gif /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [shu223] 4 | custom: ['https://paypal.me/shu223'] 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | 28 | # CocoaPods 29 | # 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 33 | 34 | Pods/ 35 | 36 | # Carthage 37 | # 38 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 39 | # Carthage/Checkouts 40 | 41 | Carthage/Build 42 | PulsingHaloDemo.xccheckout 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 shu223 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /PulsingHalo.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "PulsingHalo" 3 | s.version = "0.2.10" 4 | s.platform = :ios 5 | s.ios.deployment_target = '8.0' 6 | s.summary = "iOS Component to create Pulsating Animations." 7 | s.homepage = "https://github.com/shu223/PulsingHalo" 8 | s.license = 'MIT' 9 | s.author = { "shu223" => "shuichi0526@gmail.com" } 10 | s.source = { :git => "https://github.com/shu223/PulsingHalo.git", :tag => "0.2.10" } 11 | s.source_files = 'PulsingHalo/*.{h,m}' 12 | s.framework = 'QuartzCore' 13 | s.requires_arc = true 14 | end 15 | -------------------------------------------------------------------------------- /PulsingHalo/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /PulsingHalo/PulsingHalo.h: -------------------------------------------------------------------------------- 1 | // 2 | // PulsingHalo.h 3 | // PulsingHalo 4 | // 5 | // Created by Shuichi Tsutsumi on 3/11/16. 6 | // Copyright © 2016 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for PulsingHalo. 12 | FOUNDATION_EXPORT double PulsingHaloVersionNumber; 13 | 14 | //! Project version string for PulsingHalo. 15 | FOUNDATION_EXPORT const unsigned char PulsingHaloVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #if __has_include() 20 | #import 21 | #else 22 | #import "PulsingHaloLayer.h" 23 | #endif 24 | 25 | 26 | -------------------------------------------------------------------------------- /PulsingHalo/PulsingHaloLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // PulsingHaloLayer.h 3 | // https://github.com/shu223/PulsingHalo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | // Inspired by https://github.com/samvermette/SVPulsingAnnotationView 9 | 10 | 11 | #import 12 | #import 13 | 14 | 15 | @interface PulsingHaloLayer : CAReplicatorLayer 16 | 17 | /** 18 | * The default value of this property is @c 60pt. 19 | */ 20 | @property (nonatomic, assign) CGFloat radius; 21 | 22 | /** 23 | * The default value of this property is @c 0.0. 24 | */ 25 | @property (nonatomic, assign) CGFloat fromValueForRadius; 26 | 27 | /** 28 | * The default value of this property is @c 0.45. 29 | */ 30 | @property (nonatomic, assign) CGFloat fromValueForAlpha __attribute__ ((unavailable("Now the alpha channel of the backgroundColor is used."))); 31 | 32 | /** 33 | * The value of this property should be ranging from @c 0 to @c 1 (exclusive). 34 | * 35 | * The default value of this property is @c 0.2. 36 | */ 37 | @property (nonatomic, assign) CGFloat keyTimeForHalfOpacity; 38 | 39 | /** 40 | * The animation duration in seconds. 41 | * 42 | * The default value of this property is @c 3. 43 | */ 44 | @property (nonatomic, assign) NSTimeInterval animationDuration; 45 | 46 | /** 47 | * The animation interval in seconds. 48 | * 49 | * The default value of this property is @c 0. 50 | */ 51 | @property (nonatomic, assign) NSTimeInterval pulseInterval; 52 | 53 | /** 54 | * The default value of this property is @c YES. 55 | */ 56 | @property (nonatomic, assign) BOOL useTimingFunction; 57 | 58 | /** 59 | * The default value of this property is @c 1. 60 | */ 61 | @property (nonatomic, assign) NSInteger haloLayerNumber; 62 | 63 | /** 64 | * The animation delay in seconds. 65 | * 66 | * The default value of this property is @c 1. 67 | */ 68 | @property (nonatomic, assign) NSTimeInterval startInterval; 69 | 70 | /** 71 | * When this value is true, the halo will be automatically resumed after entering foreground. 72 | * 73 | * The default value of this property is YES. 74 | */ 75 | @property (nonatomic, assign) BOOL shouldResume; 76 | 77 | - (void)start; 78 | - (void)stop; 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /PulsingHalo/PulsingHaloLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // PulsingHaloLayer.m 3 | // https://github.com/shu223/PulsingHalo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | // Inspired by https://github.com/samvermette/SVPulsingAnnotationView 9 | 10 | 11 | #import "PulsingHaloLayer.h" 12 | 13 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 14 | @interface PulsingHaloLayer () 15 | #else 16 | @interface PulsingHaloLayer () 17 | #endif 18 | @property (nonatomic, strong) CALayer *effect; 19 | @property (nonatomic, strong) CAAnimationGroup *animationGroup; 20 | 21 | // for resume 22 | @property (nonatomic, weak) CALayer *prevSuperlayer; 23 | @property (nonatomic, assign) unsigned int prevLayerIndex; 24 | @property (nonatomic, strong) CAAnimation *prevAnimation; 25 | @end 26 | 27 | 28 | @implementation PulsingHaloLayer 29 | @dynamic repeatCount; 30 | 31 | - (instancetype)init 32 | { 33 | self = [super init]; 34 | if (self) { 35 | self.effect = [CALayer new]; 36 | self.effect.contentsScale = [UIScreen mainScreen].scale; 37 | self.effect.opacity = 0; 38 | [self addSublayer:self.effect]; 39 | 40 | [self _setupDefaults]; 41 | 42 | [[NSNotificationCenter defaultCenter] addObserver:self 43 | selector:@selector(onDidEnterBackground:) 44 | name:UIApplicationDidEnterBackgroundNotification object:nil]; 45 | 46 | [[NSNotificationCenter defaultCenter] addObserver:self 47 | selector:@selector(onWillEnterForeground:) 48 | name:UIApplicationWillEnterForegroundNotification object:nil]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void)dealloc { 54 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 55 | } 56 | 57 | - (void)onDidEnterBackground:(NSNotification *)notification { 58 | self.prevSuperlayer = self.superlayer; 59 | if (self.prevSuperlayer) { 60 | unsigned int layerIndex = 0; 61 | for (CALayer *aSublayer in self.superlayer.sublayers) { 62 | if (aSublayer == self) { 63 | self.prevLayerIndex = layerIndex; 64 | break; 65 | } 66 | layerIndex++; 67 | } 68 | } 69 | self.prevAnimation = [self.effect animationForKey:@"pulse"]; 70 | } 71 | 72 | - (void)onWillEnterForeground:(NSNotification *)notification { 73 | if (self.shouldResume) { 74 | [self _resume]; 75 | } 76 | } 77 | 78 | // ============================================================================= 79 | #pragma mark - Accessor 80 | 81 | - (void)start { 82 | [self _setupAnimationGroup]; 83 | [self.effect addAnimation:self.animationGroup forKey:@"pulse"]; 84 | } 85 | 86 | - (void)stop { 87 | [self removeAllAnimations]; 88 | self.animationGroup.delegate = nil; 89 | } 90 | 91 | - (void)setFrame:(CGRect)frame { 92 | [super setFrame:frame]; 93 | self.effect.frame = frame; 94 | } 95 | 96 | - (void)setBorderWidth:(CGFloat)borderWidth { 97 | [super setBorderWidth:borderWidth]; 98 | self.effect.borderWidth = borderWidth; 99 | } 100 | 101 | - (void)setBorderColor:(CGColorRef)borderColor { 102 | [super setBorderColor:borderColor]; 103 | self.effect.borderColor = borderColor; 104 | } 105 | 106 | - (void)setBackgroundColor:(CGColorRef)backgroundColor { 107 | [super setBackgroundColor:backgroundColor]; 108 | self.effect.backgroundColor = backgroundColor; 109 | } 110 | 111 | - (void)setRadius:(CGFloat)radius { 112 | _radius = radius; 113 | 114 | CGFloat diameter = self.radius * 2; 115 | 116 | self.effect.bounds = CGRectMake(0, 0, diameter, diameter); 117 | self.effect.cornerRadius = self.radius; 118 | } 119 | 120 | - (void)setPulseInterval:(NSTimeInterval)pulseInterval { 121 | _pulseInterval = pulseInterval; 122 | 123 | if (_pulseInterval == INFINITY) { 124 | [self.effect removeAnimationForKey:@"pulse"]; 125 | } 126 | } 127 | 128 | - (void)setHaloLayerNumber:(NSInteger)haloLayerNumber { 129 | _haloLayerNumber = haloLayerNumber; 130 | self.instanceCount = haloLayerNumber; 131 | self.instanceDelay = (self.animationDuration + self.pulseInterval) / haloLayerNumber; 132 | } 133 | 134 | - (void)setStartInterval:(NSTimeInterval)startInterval { 135 | _startInterval = startInterval; 136 | self.instanceDelay = startInterval; 137 | } 138 | 139 | - (void)setAnimationDuration:(NSTimeInterval)animationDuration { 140 | _animationDuration = animationDuration; 141 | 142 | self.instanceDelay = (self.animationDuration + self.pulseInterval) / self.haloLayerNumber; 143 | } 144 | 145 | - (void)setRepeatCount:(float)repeatCount { 146 | [super setRepeatCount:repeatCount]; 147 | self.animationGroup.repeatCount = repeatCount; 148 | } 149 | 150 | 151 | // ============================================================================= 152 | #pragma mark - Private 153 | 154 | - (void)_setupDefaults { 155 | _shouldResume = YES; 156 | _fromValueForRadius = 0.0; 157 | _keyTimeForHalfOpacity = 0.2; 158 | _animationDuration = 3; 159 | _pulseInterval = 0; 160 | _useTimingFunction = YES; 161 | 162 | self.repeatCount = INFINITY; 163 | self.radius = 60; 164 | self.haloLayerNumber = 1; 165 | self.startInterval = 1; 166 | self.backgroundColor = [[UIColor colorWithRed:0.000 green:0.455 blue:0.756 alpha:0.45] CGColor]; 167 | } 168 | 169 | - (void)_setupAnimationGroup { 170 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; 171 | animationGroup.duration = self.animationDuration + self.pulseInterval; 172 | animationGroup.repeatCount = self.repeatCount; 173 | if (self.useTimingFunction) { 174 | CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; 175 | animationGroup.timingFunction = defaultCurve; 176 | } 177 | 178 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"]; 179 | scaleAnimation.fromValue = @(self.fromValueForRadius); 180 | scaleAnimation.toValue = @1.0; 181 | scaleAnimation.duration = self.animationDuration; 182 | 183 | CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; 184 | opacityAnimation.duration = self.animationDuration; 185 | CGFloat fromValueForAlpha = CGColorGetAlpha(self.backgroundColor); 186 | opacityAnimation.values = @[@(fromValueForAlpha), @(fromValueForAlpha * 0.5), @0]; 187 | opacityAnimation.keyTimes = @[@0, @(self.keyTimeForHalfOpacity), @1]; 188 | 189 | NSArray *animations = @[scaleAnimation, opacityAnimation]; 190 | 191 | animationGroup.animations = animations; 192 | 193 | self.animationGroup = animationGroup; 194 | self.animationGroup.delegate = self; 195 | } 196 | 197 | - (void)_resume { 198 | [self addSublayer:self.effect]; 199 | [self.prevSuperlayer insertSublayer:self atIndex:self.prevLayerIndex]; 200 | if (self.prevAnimation) { 201 | [self.effect addAnimation:self.prevAnimation forKey:@"pulse"]; 202 | } 203 | } 204 | 205 | 206 | // ============================================================================= 207 | #pragma mark - CAAnimationDelegate 208 | 209 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 210 | if ([self.effect.animationKeys count]) { 211 | [self.effect removeAllAnimations]; 212 | } 213 | [self.effect removeFromSuperlayer]; 214 | [self removeFromSuperlayer]; 215 | } 216 | 217 | @end 218 | -------------------------------------------------------------------------------- /PulsingHaloDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8A76D79E1BD4CC6B00C3881D /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A76D79D1BD4CC6B00C3881D /* Launch Screen.storyboard */; }; 11 | 8AB7E7DC1C92DD87009A3BB6 /* PulsingHalo.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB7E7DB1C92DD87009A3BB6 /* PulsingHalo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 8AB7E80A1C92F6FB009A3BB6 /* PulsingHaloLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC9074B185065DB00A74F2E /* PulsingHaloLayer.m */; }; 13 | 8AB7E8121C92FEB1009A3BB6 /* PulsingHaloLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AC9074A185065DB00A74F2E /* PulsingHaloLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 8AC907151850659E00A74F2E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907141850659E00A74F2E /* Foundation.framework */; }; 15 | 8AC907171850659E00A74F2E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907161850659E00A74F2E /* CoreGraphics.framework */; }; 16 | 8AC907191850659E00A74F2E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907181850659E00A74F2E /* UIKit.framework */; }; 17 | 8AC9071F1850659E00A74F2E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8AC9071D1850659E00A74F2E /* InfoPlist.strings */; }; 18 | 8AC907211850659E00A74F2E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC907201850659E00A74F2E /* main.m */; }; 19 | 8AC907251850659E00A74F2E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC907241850659E00A74F2E /* AppDelegate.m */; }; 20 | 8AC907281850659E00A74F2E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8AC907261850659E00A74F2E /* Main.storyboard */; }; 21 | 8AC9072B1850659E00A74F2E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC9072A1850659E00A74F2E /* ViewController.m */; }; 22 | 8AC9072D1850659E00A74F2E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8AC9072C1850659E00A74F2E /* Images.xcassets */; }; 23 | 8AC907341850659E00A74F2E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907331850659E00A74F2E /* XCTest.framework */; }; 24 | 8AC907351850659E00A74F2E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907141850659E00A74F2E /* Foundation.framework */; }; 25 | 8AC907361850659E00A74F2E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC907181850659E00A74F2E /* UIKit.framework */; }; 26 | 8AC9073E1850659E00A74F2E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8AC9073C1850659E00A74F2E /* InfoPlist.strings */; }; 27 | 8AC907401850659E00A74F2E /* PulsingHaloDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC9073F1850659E00A74F2E /* PulsingHaloDemoTests.m */; }; 28 | 8AC9074C185065DB00A74F2E /* PulsingHaloLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC9074B185065DB00A74F2E /* PulsingHaloLayer.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 8AC907371850659E00A74F2E /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 8AC907091850659E00A74F2E /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 8AC907101850659E00A74F2E; 37 | remoteInfo = PulsingHaloDemo; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 8AB7E7E51C92DD88009A3BB6 /* Embed Frameworks */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | ); 49 | name = "Embed Frameworks"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 8A76D79D1BD4CC6B00C3881D /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; 56 | 8AB7E7D91C92DD87009A3BB6 /* PulsingHalo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PulsingHalo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 8AB7E7DB1C92DD87009A3BB6 /* PulsingHalo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PulsingHalo.h; sourceTree = ""; }; 58 | 8AB7E7DD1C92DD87009A3BB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 8AC907111850659E00A74F2E /* PulsingHaloDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PulsingHaloDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | 8AC907141850659E00A74F2E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 61 | 8AC907161850659E00A74F2E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 62 | 8AC907181850659E00A74F2E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 63 | 8AC9071C1850659E00A74F2E /* PulsingHaloDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PulsingHaloDemo-Info.plist"; sourceTree = ""; }; 64 | 8AC9071E1850659E00A74F2E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 65 | 8AC907201850659E00A74F2E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 66 | 8AC907221850659E00A74F2E /* PulsingHaloDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PulsingHaloDemo-Prefix.pch"; sourceTree = ""; }; 67 | 8AC907231850659E00A74F2E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 68 | 8AC907241850659E00A74F2E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 69 | 8AC907271850659E00A74F2E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 70 | 8AC907291850659E00A74F2E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 71 | 8AC9072A1850659E00A74F2E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 72 | 8AC9072C1850659E00A74F2E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 73 | 8AC907321850659E00A74F2E /* PulsingHaloDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PulsingHaloDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 8AC907331850659E00A74F2E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 75 | 8AC9073B1850659E00A74F2E /* PulsingHaloDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PulsingHaloDemoTests-Info.plist"; sourceTree = ""; }; 76 | 8AC9073D1850659E00A74F2E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 77 | 8AC9073F1850659E00A74F2E /* PulsingHaloDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PulsingHaloDemoTests.m; sourceTree = ""; }; 78 | 8AC9074A185065DB00A74F2E /* PulsingHaloLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PulsingHaloLayer.h; sourceTree = ""; }; 79 | 8AC9074B185065DB00A74F2E /* PulsingHaloLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PulsingHaloLayer.m; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 8AB7E7D51C92DD87009A3BB6 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | 8AC9070E1850659E00A74F2E /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | 8AC907171850659E00A74F2E /* CoreGraphics.framework in Frameworks */, 95 | 8AC907191850659E00A74F2E /* UIKit.framework in Frameworks */, 96 | 8AC907151850659E00A74F2E /* Foundation.framework in Frameworks */, 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | 8AC9072F1850659E00A74F2E /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | 8AC907341850659E00A74F2E /* XCTest.framework in Frameworks */, 105 | 8AC907361850659E00A74F2E /* UIKit.framework in Frameworks */, 106 | 8AC907351850659E00A74F2E /* Foundation.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXFrameworksBuildPhase section */ 111 | 112 | /* Begin PBXGroup section */ 113 | 8AB7E7DA1C92DD87009A3BB6 /* PulsingHalo */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 8AB7E7DB1C92DD87009A3BB6 /* PulsingHalo.h */, 117 | 8AC9074A185065DB00A74F2E /* PulsingHaloLayer.h */, 118 | 8AC9074B185065DB00A74F2E /* PulsingHaloLayer.m */, 119 | 8AB7E7DD1C92DD87009A3BB6 /* Info.plist */, 120 | ); 121 | path = PulsingHalo; 122 | sourceTree = ""; 123 | }; 124 | 8AC907081850659E00A74F2E = { 125 | isa = PBXGroup; 126 | children = ( 127 | 8AB7E7DA1C92DD87009A3BB6 /* PulsingHalo */, 128 | 8AC9071A1850659E00A74F2E /* PulsingHaloDemo */, 129 | 8AC907391850659E00A74F2E /* PulsingHaloDemoTests */, 130 | 8AC907131850659E00A74F2E /* Frameworks */, 131 | 8AC907121850659E00A74F2E /* Products */, 132 | ); 133 | sourceTree = ""; 134 | }; 135 | 8AC907121850659E00A74F2E /* Products */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 8AC907111850659E00A74F2E /* PulsingHaloDemo.app */, 139 | 8AC907321850659E00A74F2E /* PulsingHaloDemoTests.xctest */, 140 | 8AB7E7D91C92DD87009A3BB6 /* PulsingHalo.framework */, 141 | ); 142 | name = Products; 143 | sourceTree = ""; 144 | }; 145 | 8AC907131850659E00A74F2E /* Frameworks */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 8AC907141850659E00A74F2E /* Foundation.framework */, 149 | 8AC907161850659E00A74F2E /* CoreGraphics.framework */, 150 | 8AC907181850659E00A74F2E /* UIKit.framework */, 151 | 8AC907331850659E00A74F2E /* XCTest.framework */, 152 | ); 153 | name = Frameworks; 154 | sourceTree = ""; 155 | }; 156 | 8AC9071A1850659E00A74F2E /* PulsingHaloDemo */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 8AC9071B1850659E00A74F2E /* Supporting Files */, 160 | 8AC9072C1850659E00A74F2E /* Images.xcassets */, 161 | 8AC907261850659E00A74F2E /* Main.storyboard */, 162 | 8A76D79D1BD4CC6B00C3881D /* Launch Screen.storyboard */, 163 | 8AC907231850659E00A74F2E /* AppDelegate.h */, 164 | 8AC907241850659E00A74F2E /* AppDelegate.m */, 165 | 8AC907291850659E00A74F2E /* ViewController.h */, 166 | 8AC9072A1850659E00A74F2E /* ViewController.m */, 167 | ); 168 | path = PulsingHaloDemo; 169 | sourceTree = ""; 170 | }; 171 | 8AC9071B1850659E00A74F2E /* Supporting Files */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 8AC9071C1850659E00A74F2E /* PulsingHaloDemo-Info.plist */, 175 | 8AC9071D1850659E00A74F2E /* InfoPlist.strings */, 176 | 8AC907201850659E00A74F2E /* main.m */, 177 | 8AC907221850659E00A74F2E /* PulsingHaloDemo-Prefix.pch */, 178 | ); 179 | name = "Supporting Files"; 180 | sourceTree = ""; 181 | }; 182 | 8AC907391850659E00A74F2E /* PulsingHaloDemoTests */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 8AC9073F1850659E00A74F2E /* PulsingHaloDemoTests.m */, 186 | 8AC9073A1850659E00A74F2E /* Supporting Files */, 187 | ); 188 | path = PulsingHaloDemoTests; 189 | sourceTree = ""; 190 | }; 191 | 8AC9073A1850659E00A74F2E /* Supporting Files */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 8AC9073B1850659E00A74F2E /* PulsingHaloDemoTests-Info.plist */, 195 | 8AC9073C1850659E00A74F2E /* InfoPlist.strings */, 196 | ); 197 | name = "Supporting Files"; 198 | sourceTree = ""; 199 | }; 200 | /* End PBXGroup section */ 201 | 202 | /* Begin PBXHeadersBuildPhase section */ 203 | 8AB7E7D61C92DD87009A3BB6 /* Headers */ = { 204 | isa = PBXHeadersBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 8AB7E7DC1C92DD87009A3BB6 /* PulsingHalo.h in Headers */, 208 | 8AB7E8121C92FEB1009A3BB6 /* PulsingHaloLayer.h in Headers */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXHeadersBuildPhase section */ 213 | 214 | /* Begin PBXNativeTarget section */ 215 | 8AB7E7D81C92DD87009A3BB6 /* PulsingHalo */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = 8AB7E7E41C92DD88009A3BB6 /* Build configuration list for PBXNativeTarget "PulsingHalo" */; 218 | buildPhases = ( 219 | 8AB7E7D41C92DD87009A3BB6 /* Sources */, 220 | 8AB7E7D51C92DD87009A3BB6 /* Frameworks */, 221 | 8AB7E7D61C92DD87009A3BB6 /* Headers */, 222 | 8AB7E7D71C92DD87009A3BB6 /* Resources */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | ); 228 | name = PulsingHalo; 229 | productName = PulsingHalo; 230 | productReference = 8AB7E7D91C92DD87009A3BB6 /* PulsingHalo.framework */; 231 | productType = "com.apple.product-type.framework"; 232 | }; 233 | 8AC907101850659E00A74F2E /* PulsingHaloDemo */ = { 234 | isa = PBXNativeTarget; 235 | buildConfigurationList = 8AC907431850659E00A74F2E /* Build configuration list for PBXNativeTarget "PulsingHaloDemo" */; 236 | buildPhases = ( 237 | 8AC9070D1850659E00A74F2E /* Sources */, 238 | 8AC9070E1850659E00A74F2E /* Frameworks */, 239 | 8AC9070F1850659E00A74F2E /* Resources */, 240 | 8AB7E7E51C92DD88009A3BB6 /* Embed Frameworks */, 241 | ); 242 | buildRules = ( 243 | ); 244 | dependencies = ( 245 | ); 246 | name = PulsingHaloDemo; 247 | productName = PulsingHaloDemo; 248 | productReference = 8AC907111850659E00A74F2E /* PulsingHaloDemo.app */; 249 | productType = "com.apple.product-type.application"; 250 | }; 251 | 8AC907311850659E00A74F2E /* PulsingHaloDemoTests */ = { 252 | isa = PBXNativeTarget; 253 | buildConfigurationList = 8AC907461850659E00A74F2E /* Build configuration list for PBXNativeTarget "PulsingHaloDemoTests" */; 254 | buildPhases = ( 255 | 8AC9072E1850659E00A74F2E /* Sources */, 256 | 8AC9072F1850659E00A74F2E /* Frameworks */, 257 | 8AC907301850659E00A74F2E /* Resources */, 258 | ); 259 | buildRules = ( 260 | ); 261 | dependencies = ( 262 | 8AC907381850659E00A74F2E /* PBXTargetDependency */, 263 | ); 264 | name = PulsingHaloDemoTests; 265 | productName = PulsingHaloDemoTests; 266 | productReference = 8AC907321850659E00A74F2E /* PulsingHaloDemoTests.xctest */; 267 | productType = "com.apple.product-type.bundle.unit-test"; 268 | }; 269 | /* End PBXNativeTarget section */ 270 | 271 | /* Begin PBXProject section */ 272 | 8AC907091850659E00A74F2E /* Project object */ = { 273 | isa = PBXProject; 274 | attributes = { 275 | LastUpgradeCheck = 1300; 276 | ORGANIZATIONNAME = "Shuichi Tsutsumi"; 277 | TargetAttributes = { 278 | 8AB7E7D81C92DD87009A3BB6 = { 279 | CreatedOnToolsVersion = 7.2.1; 280 | }; 281 | 8AC907101850659E00A74F2E = { 282 | DevelopmentTeam = 9Z86A4AWDE; 283 | ProvisioningStyle = Automatic; 284 | }; 285 | 8AC907311850659E00A74F2E = { 286 | TestTargetID = 8AC907101850659E00A74F2E; 287 | }; 288 | }; 289 | }; 290 | buildConfigurationList = 8AC9070C1850659E00A74F2E /* Build configuration list for PBXProject "PulsingHaloDemo" */; 291 | compatibilityVersion = "Xcode 3.2"; 292 | developmentRegion = en; 293 | hasScannedForEncodings = 0; 294 | knownRegions = ( 295 | en, 296 | Base, 297 | ); 298 | mainGroup = 8AC907081850659E00A74F2E; 299 | productRefGroup = 8AC907121850659E00A74F2E /* Products */; 300 | projectDirPath = ""; 301 | projectRoot = ""; 302 | targets = ( 303 | 8AC907101850659E00A74F2E /* PulsingHaloDemo */, 304 | 8AC907311850659E00A74F2E /* PulsingHaloDemoTests */, 305 | 8AB7E7D81C92DD87009A3BB6 /* PulsingHalo */, 306 | ); 307 | }; 308 | /* End PBXProject section */ 309 | 310 | /* Begin PBXResourcesBuildPhase section */ 311 | 8AB7E7D71C92DD87009A3BB6 /* Resources */ = { 312 | isa = PBXResourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | 8AC9070F1850659E00A74F2E /* Resources */ = { 319 | isa = PBXResourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | 8AC9072D1850659E00A74F2E /* Images.xcassets in Resources */, 323 | 8AC9071F1850659E00A74F2E /* InfoPlist.strings in Resources */, 324 | 8A76D79E1BD4CC6B00C3881D /* Launch Screen.storyboard in Resources */, 325 | 8AC907281850659E00A74F2E /* Main.storyboard in Resources */, 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | 8AC907301850659E00A74F2E /* Resources */ = { 330 | isa = PBXResourcesBuildPhase; 331 | buildActionMask = 2147483647; 332 | files = ( 333 | 8AC9073E1850659E00A74F2E /* InfoPlist.strings in Resources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXResourcesBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | 8AB7E7D41C92DD87009A3BB6 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | 8AB7E80A1C92F6FB009A3BB6 /* PulsingHaloLayer.m in Sources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | 8AC9070D1850659E00A74F2E /* Sources */ = { 349 | isa = PBXSourcesBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | 8AC9074C185065DB00A74F2E /* PulsingHaloLayer.m in Sources */, 353 | 8AC9072B1850659E00A74F2E /* ViewController.m in Sources */, 354 | 8AC907251850659E00A74F2E /* AppDelegate.m in Sources */, 355 | 8AC907211850659E00A74F2E /* main.m in Sources */, 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | }; 359 | 8AC9072E1850659E00A74F2E /* Sources */ = { 360 | isa = PBXSourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | 8AC907401850659E00A74F2E /* PulsingHaloDemoTests.m in Sources */, 364 | ); 365 | runOnlyForDeploymentPostprocessing = 0; 366 | }; 367 | /* End PBXSourcesBuildPhase section */ 368 | 369 | /* Begin PBXTargetDependency section */ 370 | 8AC907381850659E00A74F2E /* PBXTargetDependency */ = { 371 | isa = PBXTargetDependency; 372 | target = 8AC907101850659E00A74F2E /* PulsingHaloDemo */; 373 | targetProxy = 8AC907371850659E00A74F2E /* PBXContainerItemProxy */; 374 | }; 375 | /* End PBXTargetDependency section */ 376 | 377 | /* Begin PBXVariantGroup section */ 378 | 8AC9071D1850659E00A74F2E /* InfoPlist.strings */ = { 379 | isa = PBXVariantGroup; 380 | children = ( 381 | 8AC9071E1850659E00A74F2E /* en */, 382 | ); 383 | name = InfoPlist.strings; 384 | sourceTree = ""; 385 | }; 386 | 8AC907261850659E00A74F2E /* Main.storyboard */ = { 387 | isa = PBXVariantGroup; 388 | children = ( 389 | 8AC907271850659E00A74F2E /* Base */, 390 | ); 391 | name = Main.storyboard; 392 | sourceTree = ""; 393 | }; 394 | 8AC9073C1850659E00A74F2E /* InfoPlist.strings */ = { 395 | isa = PBXVariantGroup; 396 | children = ( 397 | 8AC9073D1850659E00A74F2E /* en */, 398 | ); 399 | name = InfoPlist.strings; 400 | sourceTree = ""; 401 | }; 402 | /* End PBXVariantGroup section */ 403 | 404 | /* Begin XCBuildConfiguration section */ 405 | 8AB7E7E21C92DD88009A3BB6 /* Debug */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | CLANG_WARN_UNREACHABLE_CODE = YES; 409 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 410 | CURRENT_PROJECT_VERSION = 1; 411 | DEBUG_INFORMATION_FORMAT = dwarf; 412 | DEFINES_MODULE = YES; 413 | DYLIB_COMPATIBILITY_VERSION = 1; 414 | DYLIB_CURRENT_VERSION = 1; 415 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 416 | ENABLE_STRICT_OBJC_MSGSEND = YES; 417 | GCC_NO_COMMON_BLOCKS = YES; 418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 419 | INFOPLIST_FILE = PulsingHalo/Info.plist; 420 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 421 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 422 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 423 | MTL_ENABLE_DEBUG_INFO = YES; 424 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.PulsingHalo"; 425 | PRODUCT_NAME = "$(TARGET_NAME)"; 426 | SKIP_INSTALL = YES; 427 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 428 | TARGETED_DEVICE_FAMILY = "1,2"; 429 | VERSIONING_SYSTEM = "apple-generic"; 430 | VERSION_INFO_PREFIX = ""; 431 | }; 432 | name = Debug; 433 | }; 434 | 8AB7E7E31C92DD88009A3BB6 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | CLANG_WARN_UNREACHABLE_CODE = YES; 438 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 439 | COPY_PHASE_STRIP = NO; 440 | CURRENT_PROJECT_VERSION = 1; 441 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 442 | DEFINES_MODULE = YES; 443 | DYLIB_COMPATIBILITY_VERSION = 1; 444 | DYLIB_CURRENT_VERSION = 1; 445 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 446 | ENABLE_STRICT_OBJC_MSGSEND = YES; 447 | GCC_NO_COMMON_BLOCKS = YES; 448 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 449 | INFOPLIST_FILE = PulsingHalo/Info.plist; 450 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 451 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 453 | MTL_ENABLE_DEBUG_INFO = NO; 454 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.PulsingHalo"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | SKIP_INSTALL = YES; 457 | TARGETED_DEVICE_FAMILY = "1,2"; 458 | VERSIONING_SYSTEM = "apple-generic"; 459 | VERSION_INFO_PREFIX = ""; 460 | }; 461 | name = Release; 462 | }; 463 | 8AC907411850659E00A74F2E /* Debug */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ALWAYS_SEARCH_USER_PATHS = NO; 467 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 468 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 469 | CLANG_CXX_LIBRARY = "libc++"; 470 | CLANG_ENABLE_MODULES = YES; 471 | CLANG_ENABLE_OBJC_ARC = YES; 472 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 473 | CLANG_WARN_BOOL_CONVERSION = YES; 474 | CLANG_WARN_COMMA = YES; 475 | CLANG_WARN_CONSTANT_CONVERSION = YES; 476 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 477 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 478 | CLANG_WARN_EMPTY_BODY = YES; 479 | CLANG_WARN_ENUM_CONVERSION = YES; 480 | CLANG_WARN_INFINITE_RECURSION = YES; 481 | CLANG_WARN_INT_CONVERSION = YES; 482 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 483 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 484 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 485 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 486 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 487 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 488 | CLANG_WARN_STRICT_PROTOTYPES = YES; 489 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 490 | CLANG_WARN_UNREACHABLE_CODE = YES; 491 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 492 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 493 | COPY_PHASE_STRIP = NO; 494 | ENABLE_STRICT_OBJC_MSGSEND = YES; 495 | ENABLE_TESTABILITY = YES; 496 | GCC_C_LANGUAGE_STANDARD = gnu99; 497 | GCC_DYNAMIC_NO_PIC = NO; 498 | GCC_NO_COMMON_BLOCKS = YES; 499 | GCC_OPTIMIZATION_LEVEL = 0; 500 | GCC_PREPROCESSOR_DEFINITIONS = ( 501 | "DEBUG=1", 502 | "$(inherited)", 503 | ); 504 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 505 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 506 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 507 | GCC_WARN_UNDECLARED_SELECTOR = YES; 508 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 509 | GCC_WARN_UNUSED_FUNCTION = YES; 510 | GCC_WARN_UNUSED_VARIABLE = YES; 511 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 512 | ONLY_ACTIVE_ARCH = YES; 513 | SDKROOT = iphoneos; 514 | }; 515 | name = Debug; 516 | }; 517 | 8AC907421850659E00A74F2E /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | ALWAYS_SEARCH_USER_PATHS = NO; 521 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 522 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 523 | CLANG_CXX_LIBRARY = "libc++"; 524 | CLANG_ENABLE_MODULES = YES; 525 | CLANG_ENABLE_OBJC_ARC = YES; 526 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 527 | CLANG_WARN_BOOL_CONVERSION = YES; 528 | CLANG_WARN_COMMA = YES; 529 | CLANG_WARN_CONSTANT_CONVERSION = YES; 530 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 531 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 532 | CLANG_WARN_EMPTY_BODY = YES; 533 | CLANG_WARN_ENUM_CONVERSION = YES; 534 | CLANG_WARN_INFINITE_RECURSION = YES; 535 | CLANG_WARN_INT_CONVERSION = YES; 536 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 537 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 538 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 539 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 540 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 541 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 542 | CLANG_WARN_STRICT_PROTOTYPES = YES; 543 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 544 | CLANG_WARN_UNREACHABLE_CODE = YES; 545 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 546 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 547 | COPY_PHASE_STRIP = YES; 548 | ENABLE_NS_ASSERTIONS = NO; 549 | ENABLE_STRICT_OBJC_MSGSEND = YES; 550 | GCC_C_LANGUAGE_STANDARD = gnu99; 551 | GCC_NO_COMMON_BLOCKS = YES; 552 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 553 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 554 | GCC_WARN_UNDECLARED_SELECTOR = YES; 555 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 556 | GCC_WARN_UNUSED_FUNCTION = YES; 557 | GCC_WARN_UNUSED_VARIABLE = YES; 558 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 559 | SDKROOT = iphoneos; 560 | VALIDATE_PRODUCT = YES; 561 | }; 562 | name = Release; 563 | }; 564 | 8AC907441850659E00A74F2E /* Debug */ = { 565 | isa = XCBuildConfiguration; 566 | buildSettings = { 567 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 568 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 569 | DEVELOPMENT_TEAM = 9Z86A4AWDE; 570 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 571 | GCC_PREFIX_HEADER = "PulsingHaloDemo/PulsingHaloDemo-Prefix.pch"; 572 | INFOPLIST_FILE = "PulsingHaloDemo/PulsingHaloDemo-Info.plist"; 573 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 574 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 575 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.${PRODUCT_NAME:rfc1034identifier}"; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | WRAPPER_EXTENSION = app; 578 | }; 579 | name = Debug; 580 | }; 581 | 8AC907451850659E00A74F2E /* Release */ = { 582 | isa = XCBuildConfiguration; 583 | buildSettings = { 584 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 585 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 586 | DEVELOPMENT_TEAM = 9Z86A4AWDE; 587 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 588 | GCC_PREFIX_HEADER = "PulsingHaloDemo/PulsingHaloDemo-Prefix.pch"; 589 | INFOPLIST_FILE = "PulsingHaloDemo/PulsingHaloDemo-Info.plist"; 590 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 591 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 592 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.${PRODUCT_NAME:rfc1034identifier}"; 593 | PRODUCT_NAME = "$(TARGET_NAME)"; 594 | WRAPPER_EXTENSION = app; 595 | }; 596 | name = Release; 597 | }; 598 | 8AC907471850659E00A74F2E /* Debug */ = { 599 | isa = XCBuildConfiguration; 600 | buildSettings = { 601 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/PulsingHaloDemo.app/PulsingHaloDemo"; 602 | FRAMEWORK_SEARCH_PATHS = ( 603 | "$(SDKROOT)/Developer/Library/Frameworks", 604 | "$(inherited)", 605 | "$(DEVELOPER_FRAMEWORKS_DIR)", 606 | ); 607 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 608 | GCC_PREFIX_HEADER = "PulsingHaloDemo/PulsingHaloDemo-Prefix.pch"; 609 | GCC_PREPROCESSOR_DEFINITIONS = ( 610 | "DEBUG=1", 611 | "$(inherited)", 612 | ); 613 | INFOPLIST_FILE = "PulsingHaloDemoTests/PulsingHaloDemoTests-Info.plist"; 614 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.${PRODUCT_NAME:rfc1034identifier}"; 615 | PRODUCT_NAME = "$(TARGET_NAME)"; 616 | TEST_HOST = "$(BUNDLE_LOADER)"; 617 | WRAPPER_EXTENSION = xctest; 618 | }; 619 | name = Debug; 620 | }; 621 | 8AC907481850659E00A74F2E /* Release */ = { 622 | isa = XCBuildConfiguration; 623 | buildSettings = { 624 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/PulsingHaloDemo.app/PulsingHaloDemo"; 625 | FRAMEWORK_SEARCH_PATHS = ( 626 | "$(SDKROOT)/Developer/Library/Frameworks", 627 | "$(inherited)", 628 | "$(DEVELOPER_FRAMEWORKS_DIR)", 629 | ); 630 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 631 | GCC_PREFIX_HEADER = "PulsingHaloDemo/PulsingHaloDemo-Prefix.pch"; 632 | INFOPLIST_FILE = "PulsingHaloDemoTests/PulsingHaloDemoTests-Info.plist"; 633 | PRODUCT_BUNDLE_IDENTIFIER = "Shuichi-Tsutsumi.${PRODUCT_NAME:rfc1034identifier}"; 634 | PRODUCT_NAME = "$(TARGET_NAME)"; 635 | TEST_HOST = "$(BUNDLE_LOADER)"; 636 | WRAPPER_EXTENSION = xctest; 637 | }; 638 | name = Release; 639 | }; 640 | /* End XCBuildConfiguration section */ 641 | 642 | /* Begin XCConfigurationList section */ 643 | 8AB7E7E41C92DD88009A3BB6 /* Build configuration list for PBXNativeTarget "PulsingHalo" */ = { 644 | isa = XCConfigurationList; 645 | buildConfigurations = ( 646 | 8AB7E7E21C92DD88009A3BB6 /* Debug */, 647 | 8AB7E7E31C92DD88009A3BB6 /* Release */, 648 | ); 649 | defaultConfigurationIsVisible = 0; 650 | defaultConfigurationName = Release; 651 | }; 652 | 8AC9070C1850659E00A74F2E /* Build configuration list for PBXProject "PulsingHaloDemo" */ = { 653 | isa = XCConfigurationList; 654 | buildConfigurations = ( 655 | 8AC907411850659E00A74F2E /* Debug */, 656 | 8AC907421850659E00A74F2E /* Release */, 657 | ); 658 | defaultConfigurationIsVisible = 0; 659 | defaultConfigurationName = Release; 660 | }; 661 | 8AC907431850659E00A74F2E /* Build configuration list for PBXNativeTarget "PulsingHaloDemo" */ = { 662 | isa = XCConfigurationList; 663 | buildConfigurations = ( 664 | 8AC907441850659E00A74F2E /* Debug */, 665 | 8AC907451850659E00A74F2E /* Release */, 666 | ); 667 | defaultConfigurationIsVisible = 0; 668 | defaultConfigurationName = Release; 669 | }; 670 | 8AC907461850659E00A74F2E /* Build configuration list for PBXNativeTarget "PulsingHaloDemoTests" */ = { 671 | isa = XCConfigurationList; 672 | buildConfigurations = ( 673 | 8AC907471850659E00A74F2E /* Debug */, 674 | 8AC907481850659E00A74F2E /* Release */, 675 | ); 676 | defaultConfigurationIsVisible = 0; 677 | defaultConfigurationName = Release; 678 | }; 679 | /* End XCConfigurationList section */ 680 | }; 681 | rootObject = 8AC907091850659E00A74F2E /* Project object */; 682 | } 683 | -------------------------------------------------------------------------------- /PulsingHaloDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PulsingHaloDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PulsingHaloDemo.xcodeproj/xcshareddata/xcschemes/PulsingHalo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /PulsingHaloDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PulsingHaloDemo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PulsingHaloDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PulsingHaloDemo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /PulsingHaloDemo/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 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 99 | 105 | 111 | 117 | 123 | 129 | 135 | 141 | 147 | 153 | 159 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.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 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "Icon-Small@2x.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "Icon-Small@3x.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "Icon-40@2x.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "Icon-40@3x.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "Icon-60@2x.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "Icon-60@3x.png", 47 | "scale" : "3x" 48 | }, 49 | { 50 | "size" : "1024x1024", 51 | "idiom" : "ios-marketing", 52 | "filename" : "Icon-1024.png", 53 | "scale" : "1x" 54 | } 55 | ], 56 | "info" : { 57 | "version" : 1, 58 | "author" : "xcode" 59 | } 60 | } -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IPhone_5s.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/Image.imageset/IPhone_5s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/Image.imageset/IPhone_5s.png -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/bluetooth_book.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bluetooth_book.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PulsingHaloDemo/Images.xcassets/bluetooth_book.imageset/bluetooth_book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/PulsingHaloDemo/Images.xcassets/bluetooth_book.imageset/bluetooth_book.pdf -------------------------------------------------------------------------------- /PulsingHaloDemo/Launch Screen.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 | -------------------------------------------------------------------------------- /PulsingHaloDemo/PulsingHaloDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Launch Screen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /PulsingHaloDemo/PulsingHaloDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /PulsingHaloDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PulsingHaloDemo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PulsingHaloDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PulsingHaloDemo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Modified by ShannonChou on 14-7-8 7 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 8 | // 9 | 10 | #import "ViewController.h" 11 | #import "PulsingHaloLayer.h" 12 | 13 | #define kMaxRadius 200 14 | #define kMaxDuration 10 15 | 16 | 17 | @interface ViewController () 18 | @property (nonatomic, weak) PulsingHaloLayer *halo; 19 | @property (nonatomic, weak) IBOutlet UIImageView *beaconView; 20 | @property (nonatomic, weak) IBOutlet UISlider *countSlider; 21 | @property (nonatomic, weak) IBOutlet UISlider *radiusSlider; 22 | @property (nonatomic, weak) IBOutlet UISlider *durationSlider; 23 | @property (nonatomic, weak) IBOutlet UISlider *rSlider; 24 | @property (nonatomic, weak) IBOutlet UISlider *gSlider; 25 | @property (nonatomic, weak) IBOutlet UISlider *bSlider; 26 | @property (nonatomic, weak) IBOutlet UILabel *countLabel; 27 | @property (nonatomic, weak) IBOutlet UILabel *radiusLabel; 28 | @property (nonatomic, weak) IBOutlet UILabel *durationLabel; 29 | @property (nonatomic, weak) IBOutlet UILabel *rLabel; 30 | @property (nonatomic, weak) IBOutlet UILabel *gLabel; 31 | @property (nonatomic, weak) IBOutlet UILabel *bLabel; 32 | @end 33 | 34 | 35 | @implementation ViewController 36 | 37 | - (void)viewDidLoad 38 | { 39 | [super viewDidLoad]; 40 | 41 | // basic setup 42 | PulsingHaloLayer *layer = [PulsingHaloLayer layer]; 43 | self.halo = layer; 44 | [self.beaconView.superview.layer insertSublayer:self.halo below:self.beaconView.layer]; 45 | 46 | [self setupInitialValues]; 47 | 48 | [self.halo start]; 49 | } 50 | 51 | - (void)didReceiveMemoryWarning 52 | { 53 | [super didReceiveMemoryWarning]; 54 | } 55 | 56 | - (void)viewDidLayoutSubviews 57 | { 58 | [super viewDidLayoutSubviews]; 59 | 60 | self.halo.position = self.beaconView.center; 61 | } 62 | 63 | 64 | // ============================================================================= 65 | #pragma mark - Private 66 | 67 | - (void)setupInitialValues { 68 | 69 | self.countSlider.value = 5; 70 | [self countChanged:nil]; 71 | 72 | self.radiusSlider.value = 0.7; 73 | [self radiusChanged:nil]; 74 | 75 | self.durationSlider.value = 0.5; 76 | [self durationChanged:nil]; 77 | 78 | self.rSlider.value = 0.; 79 | self.gSlider.value = 0.455; 80 | self.bSlider.value = 0.756; 81 | [self colorChanged:nil]; 82 | } 83 | 84 | 85 | // ============================================================================= 86 | #pragma mark - IBAction 87 | 88 | - (IBAction)countChanged:(UISlider *)sender { 89 | 90 | //you can specify the number of halos by initial method or by instance property "haloLayerNumber" 91 | float value = floor(self.countSlider.value); 92 | self.halo.haloLayerNumber = value; 93 | self.countLabel.text = [@(value) stringValue]; 94 | } 95 | 96 | - (IBAction)radiusChanged:(UISlider *)sender { 97 | 98 | self.halo.radius = self.radiusSlider.value * kMaxRadius; 99 | 100 | self.radiusLabel.text = [NSString stringWithFormat:@"%.0f", self.radiusSlider.value * kMaxRadius]; 101 | } 102 | 103 | - (IBAction)durationChanged:(UISlider *)sender { 104 | 105 | self.halo.animationDuration = self.durationSlider.value * kMaxDuration; 106 | 107 | self.durationLabel.text = [NSString stringWithFormat:@"%.1f", self.durationSlider.value * kMaxDuration]; 108 | } 109 | 110 | - (IBAction)colorChanged:(UISlider *)sender { 111 | 112 | UIColor *color = [UIColor colorWithRed:self.rSlider.value 113 | green:self.gSlider.value 114 | blue:self.bSlider.value 115 | alpha:1.0]; 116 | 117 | [self.halo setBackgroundColor:color.CGColor]; 118 | 119 | self.rLabel.text = [NSString stringWithFormat:@"%.2f", self.rSlider.value]; 120 | self.gLabel.text = [NSString stringWithFormat:@"%.2f", self.gSlider.value]; 121 | self.bLabel.text = [NSString stringWithFormat:@"%.2f", self.bSlider.value]; 122 | } 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /PulsingHaloDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /PulsingHaloDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PulsingHaloDemo 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PulsingHaloDemoTests/PulsingHaloDemoTests-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 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PulsingHaloDemoTests/PulsingHaloDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PulsingHaloDemoTests.m 3 | // PulsingHaloDemoTests 4 | // 5 | // Created by shuichi on 12/5/13. 6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PulsingHaloDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation PulsingHaloDemoTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /PulsingHaloDemoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PulsingHalo 2 | =========== 3 | 4 | **PulsingHalo has been discontinued, and is no longer being maintained.** Please check out **[Pulsator](https://github.com/shu223/Pulsator)** which is the new version of this written with Swift. 5 | 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | [![Badge w/ Version](http://cocoapod-badges.herokuapp.com/v/PulsingHalo/badge.png)](http://cocoadocs.org/docsets/PulsingHalo) 8 | [![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat 9 | )](http://mit-license.org) 10 | 11 | iOS component for creating a pulsing animation. It allows you to create halos. 12 | 13 | ![](demo_.gif) 14 | 15 | Great For: 16 | 17 | - **Pulses of beacons (iBeacon)** 18 | - Map Annotations 19 | 20 | 21 | ## Installation 22 | 23 | ### CocoaPods 24 | 25 | Add into your Podfile. 26 | 27 | ``` 28 | pod "PulsingHalo" 29 | ``` 30 | 31 | Then `$ pod install` 32 | 33 | 34 | ### Carthage 35 | 36 | Add into your Cartfile. 37 | 38 | ``` 39 | github "shu223/PulsingHalo" 40 | ``` 41 | 42 | Then `$ carthage update` 43 | 44 | 45 | ### Manual 46 | 47 | Add PulsingHaloLayer.h,m into your project. 48 | 49 | ## How to use 50 | 51 | Just **initiate and add** to your view layer. 52 | 53 | ### Swift 54 | 55 | ```swift 56 | let halo = PulsingHaloLayer() 57 | halo.position = view.center 58 | view.layer.addSublayer(halo) 59 | halo.start() 60 | ``` 61 | 62 | ### Objective-C 63 | 64 | ```objc 65 | PulsingHaloLayer *halo = [PulsingHaloLayer layer]; 66 | halo.position = self.view.center; 67 | [self.view.layer addSublayer:halo]; 68 | [halo start]; 69 | ``` 70 | 71 | 72 | 73 | 74 | ## Customizations 75 | 76 | ### Number of Halos 77 | 78 | Use `haloLayerNumber` property. 79 | 80 | ```objc 81 | halo.haloLayerNumber = 3; 82 | ``` 83 | 84 | ### radius 85 | 86 | Use `radius` property. 87 | 88 | ```objc 89 | self.halo.radius = 240.0; 90 | ``` 91 | 92 | ### color 93 | 94 | Use `backgroundColor` property. 95 | 96 | ```objc 97 | UIColor *color = [UIColor colorWithRed:0.7 98 | green:0.9 99 | blue:0.3 100 | alpha:1.0]; 101 | 102 | self.halo.backgroundColor = color.CGColor; 103 | ``` 104 | 105 | ### animation duration 106 | 107 | Use `animationDuration` or `pulseInterval` property. 108 | 109 | 110 | ### animation repeat count 111 | 112 | Initialize using `initWithRepeatCount:` method, or set `repeatCount` property. The default value is `INFINITY`. 113 | 114 | 115 | ### animation key values and times 116 | 117 | Use properties `fromValueForRadius` or `keyTimeForHalfOpacity`. 118 | 119 | ### enable/disable timing function for animation 120 | 121 | Use property `useTimingFunction` 122 | 123 | ## Demo 124 | 125 | You can try to change the radius and color properties with demo app. 126 | 127 | 128 | ## Special Thanks 129 | 130 | Inspired by [SVPulsingAnnotationView](https://github.com/samvermette/SVPulsingAnnotationView). 131 | 132 | ## Author 133 | 134 | **Shuichi Tsutsumi** 135 | 136 | iOS freelancer in Japan. Welcome works from abroad! 137 | 138 | 139 | Support via PayPal 140 | 141 | 142 | - PAST WORKS: [My Profile Summary](https://medium.com/@shu223/my-profile-summary-f14bfc1e7099#.vdh0i7clr) 143 | - PROFILES: [LinkedIn](https://www.linkedin.com/in/shuichi-tsutsumi-525b755b/) 144 | - BLOG: [English](https://medium.com/@shu223/) / [Japanese](http://d.hatena.ne.jp/shu223/) 145 | - CONTACTS: 146 | - [Twitter](https://twitter.com/shu223) 147 | - [Facebook](https://www.facebook.com/shuichi.tsutsumi) 148 | -------------------------------------------------------------------------------- /demo_.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shu223/PulsingHalo/c4cdee6a365914c769420d0eb6c197a65e5f7f06/demo_.gif --------------------------------------------------------------------------------