2011年12月5日月曜日

Webページの表示仕方

WebページはUIWebViewで簡単に表示できるが、その中に画像の貼り付けなどがある場合、
その参照を解決する指定が必要になる。

クラスはこんな感じ。外部のURLへのリンクを貼る場合は、その確認のためUIAlertViewを表示する必要があるため、UIAlertViewDelegateも必要となる。

@interface HTMLViewController : UIViewController
<
UIWebViewDelegate,UIAlertViewDelegate
>
{
    IBOutlet    UIWebView *webView;
    NSURL       *url;
    UIAlertView *aview;
    BOOL        fopenAlert;
}
@property (nonatomic, retain) UIAlertView *aview;
ここではwebViewを含むnibを別途読み込んでいる。
(だからIBOutletがある。)

nib上でwebViewに以下の属性をチェックしておく。
Scaling Scales Page Fit
Detection Links
HTMLの読み込みはviewDidLoadで行う。

NSString *path=[[NSBundle mainBundle]pathForResource:@"HTMLファイル名" ofType:@"html"]; // リソース内のパスを得る
    NSString *html=[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
    NSURL *base=[NSURL fileURLWithPath:path]; // HTML内の画像のリンクを解決するため、これが非常に重要

表示
[webView loadHTMLString:html baseURL:base];
読み込んでからの設定が必要
webView.delegate=self;
    aview.delegate  =self; // 念のため
    url=nil;

    aview=[[UIAlertView alloc]initWithTitle:@"リンク"
                                    message:@"サポートページを開きますか?"
                                   delegate:self
                          cancelButtonTitle:@"いいえ"
                          otherButtonTitles:@"はい",nil];
    //
    fopenAlert=NO; // アラートを表示していないフラグ
    ~

HTML内のリンク(a href=)はそのままではwebView内で開いてしまうので、
内部のリンクはそのまま、外部へのリンクはSafariブラウザが開くように処理を差し替える。
そのため、webViewからのデリゲートを使う。

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    switch (navigationType) {
        case UIWebViewNavigationTypeLinkClicked: // リンクがクリックされたとき
            { // switch内でローカル変数を作るときはスコープ宣言が必須
            NSURL *url0=[request URL];
            if ([[url0 scheme]hasPrefix:@"file"]) {
                break; // file:の時は内部なので、何もしないで開けば良い
            }
           
            // 外部へのリンクの時は、飛ぶ前にUIAlertViewで確認する
            // 確認なしで飛ぶアプリも多いが、アップルの仕様書中では「確認せよ」と書いてある。
 
            url = [url0 copy]; // copyしないと消えてしまうので要注意
            } // ローカルスコープ
            [aview show]; // 表示したらすぐ終わる
            fopenAlert=YES; // アラートを表示しているフラグ
            return(FALSE);
        defalt:
            break;
    }
    return(TRUE);
}
urlをcopy属性で保存しているのは、アラートビューは独立して実行されるからである。

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
// アラートビューでボタンがクリックされた時に呼び出されるデリゲート
{
    NSLog(@"button=%d",buttonIndex);
    if (buttonIndex!=alertView.cancelButtonIndex) { // 「はい」のとき
        NSLog(@"直前url=%@",url);
        // リンクへ飛ぶ
        [[UIApplication sharedApplication] openURL:url]; // httpがあるので自動的にブラウザが立ち上がる
    }
}

- (void)dealloc
{
    webView.delegate=nil; // なんか必要なのだそうな
    if (url!=nil) [url release]; // copy属性だから
    [aview release];
    [webView release];
    [super dealloc];
}
画面の回転を有効にしている場合、回転ごとに内容の再読込をしないと画面幅が調整されない。

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
// 回転検出
{
    [webView reload]; // こうしないと画面幅が調整されないので
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // 回転有効
    return YES;
}
「重要」なこと。
UIWebViewで扱う文字エンコードはUTF-8にしないといけない。
HTML内のエンコード指定

とファイル自身の文字エンコードをUTF-8にするのを忘れないように。
(秀丸エディタだとファイル書き出し時に文字コードが指定できて楽。)









0 件のコメント:

コメントを投稿