こんにちは、気持ちは若手のponpoko1968です。
iPhoneアプリを作っていて、ロゴやアイコンなどの画像を表示したい事って、多いですよね。そういった場合、ラスター画像データは簡単に表示できますが、画面を拡大させたときに、画像が荒れてしまいます。
そこで、拡大しても画像が荒れない、illustratorやInkScapeなどで作成されたストロークデータを使いたいと思いました。
ところが、ストロークデータのファイル形式のなかでも標準化されている「SVG」形式のファイルを使おうと思ったのですが、意外と目的に合ったライブラリが見つからなかったりします。
iPhoneではUIWebViewというWebKitをラップしたビュー部品が用意されており、WebKitには、「SVG」というストロークデータの画像を表示する機能が備わっています。
そこで、SVGの表示にUIWebViewが使えないか試してみました。
方針としては、画面全体を表すビューを作成し、その子ビューとしてUIWebViewを配置することにします。画面全体のビューのviewDidLoadに処理を加え、ビューがロードされた時点でSVG表示用のビューを生成します。
NSData* image = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Logo" ofType:@"svg"]];
まず、SVGファイルのデータをNSDataに読み込みます。
UIWebView* logoView = [[UIWebView alloc] init];
[logoView loadData:image MIMEType:@"image/svg+xml" textEncodingName:@"utf-8" baseURL:nil];
UIWebViewを作成し、SVGデータを設定します。これだけでSVGデータは表示可能なのですが、このままだとUIWebViewの背景色でUIWebViewの領域が白く塗りつぶされてしまいます。
logoView.opaque = NO;
logoView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.0];
の2行を追加すると、ロゴ画像の背景部分が透過して表示されます。
[self.view addSubview:logoView];
ロゴのUIWebViewをサブビューにして完了です。
※いろいろ実験したのですが、残念なことに、このビューに対してCore Animationの機能を用いて拡大縮小アニメーション操作を加えても、最初にラスタライズされた画像イメージをそのまま操作対象としてしまい、キレイに表示されません。
UIWebViewにはstringByEvaluatingJavaScriptFromString:という、外部からJavaScript文字列を適用するメソッドが用意されているので、JavaScriptでUIWebView内部の画像を操作することで拡大縮小には対応出来そうです。
JavaScriptを有効にするにはUIWebViewの内容をhtmlドキュメントとして認識させる必要があるため、SVGの読み込みの部分を下記のように変更します。
NSString *imagePath = [[NSBundle mainBundle] resourcePath];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSString *HTMLData = @"<img src="\"Logo.svg\"" />";
NSString *urlString = [NSString stringWithFormat:@"file:/%@//",imagePath];
NSLog(urlString);
[logoView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: urlString]];