Google

2015年5月7日木曜日

UIScrollViewのキャプチャiOS8版

突発思い出し記事です。

仕事中にUIScrollViewのキャプチャがしたくて探したものの日本語記事が見当たらず。
いや、あるにはあるんですが、iOS8以降の記事がなんかなかったので備忘録として記載します。

そもそも単にUIScrollViewのキャプチャがしたいと思ってやり方忘れてたので検索。
よくあるコンテキストを持ってきて、UIImageに、、、ってやったら画像が途切れてしまってる。
うーん、気づいたらiOS8で仕様が変わってたみたい。
皆さん知ってるんだろうけど何故か記事が、、(探し方が下手?)

で、海外の記事で解決策がちらっとあったんですが、それがこんな方法でした。

・自分でUIViewを作ってその下にスクロールビュー付けてキャプチャすればいい

ただ、サンプルがSwiftだったので、自分でObj-Cにすることに。
ってことで適当に書いてみました。


- (UIImage*)imageFromView:(UIScrollView *)view
{
        // 戻りを準備
        UIImage *capturedImage;
        // 撮影専用のUIViewを準備
        UIView* tmp_view = [[UIView alloc] init];
        // スクロールビューのサイズを準備
        CGRect scr_rect = CGRectMake(0, 0, view.contentSize.width, view.contentSize.height);
        // 撮影用ビューのサイズをスクロールビューと同一に
        tmp_view.frame = scr_rect;
        // 注!ここも大事
        view.frame = scr_rect;

        // あとはよくあるパターンで。撮影用ビューが対象である点に注意。
        UIGraphicsBeginImageContextWithOptions(view.contentSize, NO, 0.0f);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [tmp_view.layer renderInContext:context];
        capturedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return capturedImage;
}

もしスクロールビューの位置が一番上じゃないのなら、これを入れて強制的に一番上にする必要があります。


        view.contentOffset = CGPointMake(0,0);

最初はこれで行けると思ってたら、やっぱり画像が途切れてしまうはめに。
スクロールビューには2つのサイズが有ることを忘れて、下線の部分が抜けていた訳です。
要は全体サイズと枠サイズがあり、窓でクリッピングされている関係からキャプチャされる画像も窓で切られてしまっていたという事でした。
なのでここでスクロールビューのサイズも全体にすることで、やっとこさ希望する処理になりました。

あとは大事な点として、上記コードでは一時的なUIViewにスクロールビューを子供として紐付けてしまっているため、撮影が成功したら元に戻さなくてはなりません。
窓枠やスクロール位置なども一緒に戻す必要もあります。
autorelease等も必要に応じて入れるのもお忘れなく。


0 件のコメント:

コメントを投稿