こんにちは。きんくまです。
前回UIViewのキャプチャの取り方について書いたのですが、あのあと上手く取れない場合があったので、メモです。
今回は、sublayerで動的に描画していた部分が空になってしまって、うまく取得できない状態でした。
解決方法は記事タイトルの通りなのですが、どうしたものかとCALayerのドキュメントを眺めていたら、良さそうなプロパティのpresentationLayerがあってそいつを使うと大丈夫でした。
具体的には、こんな感じ
+ (UIImage *)capturedImageWithView:(UIView *)aView { UIGraphicsBeginImageContextWithOptions(aView.bounds.size, NO, 0); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGPoint pt = aView.layer.frame.origin; CGContextSaveGState(ctx); CGContextTranslateCTM(ctx, pt.x, pt.y); [[aView.layer presentationLayer] renderInContext:ctx]; //ココです! UIImage *tempImg = UIGraphicsGetImageFromCurrentImageContext(); CGContextRestoreGState(ctx); UIGraphicsEndImageContext(); return tempImg; }
調べてみると、アニメーションしている場合もこれを使うと良いみたいです。
で、あとメインスレッドからこのメソッドを呼ばないと、原因不明でアプリが落ちる場合がありました。落ちたり落ちなかったり。
具体的には、renderInContext: を使ったときに、[なんかのObject drawLayer:inContext:] がunrecognized selectorだったり、Bad Accessみたいなエラーが出て落ちる感じです。なんかのObjectというのは、引数に読んでいるUIViewのsubviewの中の関連するオブジェクトだったりします。UIScrollViewDelayedTouchesBeganGestureRecognizerという、すごい長い名前のオブジェクトだったり、そうじゃなかったり、すごく不安定。
とにかくメインスレッドから呼ぶと、落ちなくなりました。
教訓)ViewやLayer関連をなんかするときは、メインスレッドから呼ぶべし!
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ