ビーコン的な演出をする for iBeacon

この記事は iBeacon Advent Calendar 4日目の記事ですが、 **iBeacon の話は一切出てきません。** [^1] 　

それどころかiOS7の新機能の話もなく、iOSの古の時代からある Core Animation を使用してビーコン的な演出 [^2] をするクラスをつくったので、その紹介でお茶を濁そうと思います。


##こういうの

![](http://f.cl.ly/items/220D2F210D1x1D0L1Q20/beacon__.gif)


##ダウンロード

ソース一式を GitHub に置いてあります。

[PulsingHalo](https://github.com/shu223/PulsingHalo)


##使い方


PulsingHaloLayer (h,m) をプロジェクトに追加し、CALayer オブジェクトとして **`addSublayer` するだけ** 。

````
PulsingHaloLayer *halo = [PulsingHaloLayer layer];
halo.position = self.view.center;
[self.view.layer addSublayer:halo];
````


##カスタマイズ

###大きさを変える

`radius` プロパティに所望の値をセットすれば、半径が変わります。

````
self.halo.radius = 240.0;
````

###色を変える

CALayer にもともとある、`backgroundColor` に CGColorRef 型の値をセットします。

````
UIColor *color = [UIColor colorWithRed:0.7
                                 green:0.9
                                  blue:0.3
                                 alpha:1.0];

self.halo.backgroundColor = color.CGColor;
````

###アニメーションの速度を変える

パルスの広がる速さについては `animationDuration` を、パルス間隔については `pulseInterval` を調整してください。


##デモ

半径、色のプロパティについてはリポジトリに同梱されているデモプロジェクトで挙動を確認できます。

![](http://f.cl.ly/items/031W0P1T190q382P063m/beacon_demo3.jpg)


##しくみ

- CALayer のサブクラスとして実装
- CALayer の `cornerRadius` プロパティで円形にしている
- CAAnimationGroup で、x,y方向のscaleと、opacityのアニメーションを行っている

````
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
scaleAnimation.fromValue = @0.0;
scaleAnimation.toValue = @1.0;
scaleAnimation.duration = self.animationDuration;

CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.duration = self.animationDuration;
opacityAnimation.values = @[@0.45, @0.45, @0];
opacityAnimation.keyTimes = @[@0, @0.2, @1];
opacityAnimation.removedOnCompletion = NO;

NSArray *animations = @[scaleAnimation, opacityAnimation];

self.animationGroup.animations = animations;
````

##参考

ソースは下記OSSを参考にさせていただきました。

[SVPulsingAnnotationView](https://github.com/samvermette/SVPulsingAnnotationView)


##（追記）複数パルスをサポートしました！

iBeaconアドベントカレンダーに名乗りを上げたものの、iBeaconをまったく触る時間がなく、逃げの一手としてつくった本ライブラリでしたが、その後（意外にも）OSSとして人気が出て、ありがたいことに pull request もちょくちょくいただくようになりました。

そんな中で、待望の **複数パルス表示** のプルリクをいただいたので、ぜひその素晴らしい新機能をご紹介したいと思います。

下のgifアニの右側のような感じです。

![](https://camo.githubusercontent.com/ddec8ff304ce4e553636bec650c053eefc0069f1/687474703a2f2f662e636c2e6c792f6974656d732f3251305830353270326d3337316d3077324f30432f68616c6f6769662e676966)


###実装方法

MultiplePulsingHaloLayer というクラスを使用します。

```
MultiplePulsingHaloLayer *multiLayer = [[MultiplePulsingHaloLayer alloc] initWithHaloLayerNum:3 andStartInterval:1];
multiLayer.position = self.view.center;
[multiLayer buildSublayers];
[self.view.layer addSublayer:multiLayer];
```

単発パルスと比べて増えた手順は

- 初期化時に引数を渡す
- `buildSublayers` を呼ぶ

だけ！


##（追記）iBeaconを2台のiPhoneで試せるサンプル

iOS7の **新機能のサンプルコード** を約20種詰め込んだオープンソースアプリ [iOS7 Sampler](http://d.hatena.ne.jp/shu223/20130924/1379990718) に、iBeacon のサンプルを追加しました。

https://github.com/shu223/iOS7-Sampler

2台のiPhoneを使用して、一方をビーコン（Peripheral）、もう一方を監視側（Central）として iBeacon の挙動を試すことができます。

PulsingHaloも内部で用いています。

- 参考にした記事
  - [[iOS 7] 新たな領域観測サービス iBeacon を使ってみる ｜ Developers.IO](http://dev.classmethod.jp/references/ios7-ibeacon-api/)
  - [iBeacon Tips: 正しいビーコン監視方法 | ブライテクノBlog](http://brightechno.com/blog/archives/220)



[^1]: iBeaconとはなんぞや、というところから勉強しつつ何か書こうと思っていたのですが、いざ勉強しようと [ここ](http://qiita.com/hedjirog/items/abd48a55387891cc8503) を見たら書きたかったネタが全部既出となっていました

[^2]: Estimote のアプリでもこういう演出をしていたので、こういうのがビーコン的なのかなと。。

[^3]: 2013年12月5日現在17種ですが、日々増えていくのでざっくり20としました。