CAShapeLayer で描写した図形を消すには?

CAShapeLayer で描写した図形を消そうと、

    CAShapeLayer* circleLayer;

    /*

  描写する部分、省略

     */

    [circleLayer removeFromSuperlayer];

とすると、消えない。

 

なんで?と思って調べたら、

    [circleLayer removeFromSuperlayer];

    circleLayer = nil;

とすると消えることが判明。めんどくさいね。

 Apple のリファレンス見たら、

You can use this method to remove a layer (and all of its sublayers) from a layer hierarchy. This method updates both the superlayer’s list of sublayers and sets this layer’s superlayerproperty to nil.

はいはい、ちゃんと書いてあるね。

 

SKShapeNode で線の先端を丸くするには・・・

SKShapeNode で線を引くと、デフォルトで先端は角ばっています。

今作っているゲームでは、これがちょっと具合が悪いというか、先端を丸くしたいと思い調べて見たところ、こんなプロパティが・・・

some_SKShapeNode.lineCap

指定できる値は 3 種。

kCALineCapButt...これが default

kCALineCapRound

kCALineCapSquare

 

kCALineCapRound を指定すると先端が丸くなりました。

指定できる変数名含めて、わかりにくいですね。

iOS 10、株価(アプリ)でちょっとした変化。

iOS 10 になってから(だと思う)、株価(アプリ)にちょっとした変化があった。

個別銘柄の株価と対比する目的でインデックスを表示したく、日経 225 を表示していました。検索で「225」とすると見つかりますので、それを表示するようにします。

株価では、個別の銘柄のニュース、売買高、時系列グラフを表示できます。日経 225 のようなインデックスでは、なぜかニュースが表示されません。場中の状況を知りたければ必要に応じて日経新聞の HP なんかを見ると確認できますが、株価アプリで一覧で表示できた方がアプリを切り替える必要がなくて断然便利です。

これまでは、なぜかインデックスものはニュースが表示されなかったですが iOS 10 になってからは表示されるようになりました。アップデートされたのですかね?

なんにせよ便利になって良かったです。

UIView の座標系と SpriteKit の座標系を変換する

SpriteKit の scene の座標系は、原点 (0, 0) が左下です。UIView の座標系は Mac でおなじみの右上になります。なぜこのような違いが出るのかというと、これは想像ですが、SpriteKit は重力の概念があり、0 は ground の方が都合がよく、計算のコストを低くできるってことなんだろうと思います。

SKScene に CALayer を追加しようとすると、SKNode は左下が原点、CALayer の path は左上が原点ということになり、オブジェクトを表示しようとするときに少し困ります。要は、Y 座標が変換できればそれでよいので、view の高さを測って座標返還するのかな、あーメンドクセーと思っていたら、こんなメソッドを発見。

 - (CGPoint) convertPointFromView:(CGPoint) point

使い方が少しわかんなかったんですが、こんな感じで OK.

some_object.position = [self convertPointFromView: some_object.position];

便利なメソッドがあるものです。

デスクトップの順番を固定する:macOS Sierra

Mavericks あたりからだったか、仮想デスクトップ(最近この言い方しないね。なんでだろ)を使えるようになって、デスクトップを複数持てて便利。仮想デスクトップは、Linux で AfterStep を使っていた頃から重宝していて、MacOS でデスクトップをクリックしてもウインドウが最前面に来なくなって久しいですが、このせいもあり、特に重宝する機能です。

でも、少し問題があって、デスクトップが指定した順番にならないというか、いつのまにか勝手に順番が変わってしまう現象が・・・

私の場合、順番は次の通りがベスト。

 第一デスクトップ:ブラウザ、メール

 第二デスクトップ:Xcode

 第三デスクトップ:Terminal, Finder, RadioTunes.com のプレイヤー(ブラウザ)

第一デスクトップと第二デスクトップを頻繁に行き来して、第三は必要な時に使うという形。

El Capitan あたりから、なぜかデスクトップの順番が勝手に変わってしまう。具体的には第三デスクトップに指定しているものが勝手に第二デスクトップになってしまうのです。なんじゃこりゃ?バグじゃないかと思っていて、バージョン上がったら治るかなと思っていたのですが、Sierra にアップデートしても現象再現。なんかおかしいなぁと思って、設定をいじっていたら、Mission Control の設定に以下の項目を発見。

  □ 最新の使用状況に基づいて操作スペースを自動的に並べ替える

このチェックを外したらデスクトップの並び順が固定になりました。ってか、このチェックなんだこりゃ。こんなもの On にするとなんの役に立つのだ?余計なことすんなよって感じ。例えると、オートマの車に乗っていると、うーん、シフトダウンのタイミングちょっと違和感・・・みたいなものでしょうか。ってか、デフォで OFF にしておいてほしいものです。

 

KVO の勘所

アプリを作っていると、「ある値が変化したら・・・」ということをしたくなるもので、KVO と呼ばれる仕組みが Objective-C に用意されています。

「あるクラスの値が変化したら知らせてね」ということを登録できます。便利なんですが、覚えておかないといけないことが 3 つほど。

1. 監視できるのはプロパティで登録しているもの。

同じクラス内の値を監視しようとして、うまく通知が送られないことがあり、なんでかよくわからないことがたまにあったのですが、監視できるのはプロパティだけです。監視したければ、property 登録しろと。知らないとはまります。

 

2. クラスが破棄されるタイミングで通知は消されません。必ず手動で消しましょう。

例えば、ゲームを作っていて通知を登録して画面を切り替えたとたん落ちる、なんでだ?と思ったら通知を消していなかったからということが割とあります。

クラスが消えるタイミングで通知も消えて欲しいところですが残ってしまいます。手動で消しましょう。

これを知らないとはまります。

 

3. options が結構曲者

監視している property 変更の前後の値を知りたければ、options で NSKeyValueObservingOptionNew または、NSKeyValueObservingOptionOld を指定できます。

property で int を監視していて、変化前後の値は特に知りたくなかったんですが、New を指定していたら、エラー発生。理由がさっぱりわからず、options:0 としたらエラーは出なくなりました。

多分、監視対象にしている property の問題だと思いますが、 前後の値を特に知りたくない時には options に 0 が指定でき、それが、謎のエラー回避の方法にもなるんだなと。

 

SpriteKit: すべての子ノードを削除する

SpriteKit で、画面上にスワイプでスクロールさせたかったのですが、解説読んでもさっぱり分かりません。自作されている方もいるようで、幾つかソースも見たのですが、それでもさっぱり分かりません。仕方ないので、左右にスワイプしてページを切り替えることにしました。

 

[self.view presentScene:self transition:transition];

 

のように指定したのですが、不幸なことに、SKLabel が重なって表示され訳わからない表示に・・・self に画面遷移しているので、先に描写している node が残ってしまうのでしょう。画面遷移する前に、一度子ノードを全て削除したいところ。

調べたところ、全ての子ノードを削除するのにうってつけのメソッドがありました。

        [self removeAllChildren];

これで、一度に全部の子ノードを削除できます。まずは子ノードを配列に入れて、それからそれから、for 文で回して・・・というのを考えていたので、すごい便利でした。