こんにちは、気持ちは若手の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の領域が白く塗りつぶされてしまいます。 screenshot-01

  logoView.opaque = NO;
  logoView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.0];
の2行を追加すると、ロゴ画像の背景部分が透過して表示されます。 screenshot-02


  [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]];