読者です 読者をやめる 読者になる 読者になる

SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.iOS Webビュー

【 Xamarin 記事一覧 】


1 表示

f:id:furuya02:20140713160655p:plain:w150:left

UIWebViewを使用して、ブラウザと同じようにWebコンテンツを表示できます。

LoadRequestメソッドでURLを指定すると、HTTPリクエストを送信し、コンテンツを取得します。
ScalesPageToFitでWebページの拡大縮小の可否を指定します。デフォルトではfalseですが、trueにセットすることで、コンテンツがビューにフィットすることになります。
Webビュ-では、コンテンツはスクロールビューの上に表示されていますが、プロパティScrollViewでこのUIScrollViewにアクセスが可能になっています。

public override void ViewDidLoad(){
    base.ViewDidLoad();
            
    //Webビューの位置が分かりやすいようにバックを黒にした
    View.BackgroundColor = UIColor.Black;
            
    //Webビューの生成
    var webView = new UIWebView(new RectangleF(0, 0, 300, 200)){
        Center = View.Center, //中央に表示
        ScalesPageToFit = true//Webページの拡大縮小の可否
    };
    webView.LoadRequest(new NSUrlRequest(new NSUrl("http://www.sapporoworks.ne.jp")));//リクエスト送信
    View.Add(webView);//Webビュ-の追加
}

2 ローカルファイルの表示

f:id:furuya02:20140713160716p:plain:w250:left

プロジェクト内の相対パスとバンドルパスを結合してフルパスを取得し、同様にLoadRequest()に渡します。

var fileName = Path.Combine(NSBundle.MainBundle.BundlePath, "Content/sample.html");
webView.LoadRequest(new NSUrlRequest(new NSUrl(fileName, false)));

プログラム内で生成したHTMLは、LoadHtmlString()で表示することができます。
この際、第2パラメータでコンテンツのパスを指定しておくと、CSSやJSなどの外部ファイルも読み込むことができます。

var contentDir = Path.Combine(NSBundle.MainBundle.BundlePath, "Content/");
const string html = "<html><head><link rel=\"stylesheet\" href=\"my.css\"></head><a href='Sample.html'>Sample.html</a></html>";
webView.LoadHtmlString(html, new NSUrl(contentDir, true));

3 簡易Webブラウザの作成

f:id:furuya02:20140713160740p:plain:w300:left
ストーリーボードを使用して、いくつかナビゲーション用ボタン等を置き、イベント処理を記述してみました。

public override void ViewDidLoad() {
    base.ViewDidLoad();

    //Loadボタン
    buttonLoad.TouchUpInside += (sender, args) =>{
        webView.LoadRequest(new NSUrlRequest(new NSUrl(textBoxUrl.Text)));
    };
    //Backボタン
    buttonBack.TouchUpInside += (sender, args) => {
        webView.GoBack();
    };
    //Forwardボタン
    buttonForward.TouchUpInside += (sender, args) => {
        webView.GoForward();
    };
    //Stopボタン
    buttonForward.TouchUpInside += (sender, args) => {
        webView.StopLoading();
    };
    //Refreshボタン
    buttonRefresh.TouchUpInside += (sender, args) => {
        webView.Reload();
    };
    
    //ロード開始時
    webView.LoadStarted += (sender, args) => {
        //ネットワークアクティブインジケータ設定
        UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
        //実際のリクエスト行(リダイレクト時などは、ロードがリクエスト指定したものとは限らないため)
        var url = webView.Request.Url.AbsoluteString;
        //入力行にコピー
        textBoxUrl.Text = url;
        //ステータス表示
        labelStatus.Text = String.Format("LoadStarted {0}", url);
        InitButton(true);//ボタン状態の初期化
    };
            
    //ロード完了時
    webView.LoadFinished += (sender, args) => {
        //ネットワークアクティブインジケータ設定
        UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
        //ステータス表示
        labelStatus.Text = "LoadFinished";
        InitButton(false);//ボタン状態の初期化
    };
    //エラー発生時
    webView.LoadError += (sender, e) => {
        //ネットワークアクティブインジケータ設定
        UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
        //ステータス表示
        labelStatus.Text = "LoadError";
        //エラーの内容をダイアログ表示する
        (new UIAlertView("ERROR",e.Error.LocalizedDescription,null,"OK",null)).Show();
        InitButton(true);//ボタン状態の初期化
    };

    //ボタン状態の初期化
    InitButton(false);
}

//ボタン状態の初期化
void InitButton(bool isLoading){
    buttonBack.Enabled = webView.CanGoBack;//戻るボタンの有効・無効
    buttonForward.Enabled = webView.CanGoForward;//進むボタンの有効・無効
    buttonStop.Enabled = isLoading; //ロード中に有効
    buttonRefresh.Enabled = !isLoading;//ロード中は無効
}

f:id:furuya02:20140713160817p:plain:w150:leftf:id:furuya02:20140713160816p:plain:w150:left

実際に動作している様子です。

4 ロード時の処理分岐

WebビューのプロパティShouldStartLoadにデリゲートをセットして、ロード開始時の動作をトラップできます。
サンプルでは、リンクを押下時にデフォルトのブラウザ(Safari)を開くようにしました。

//Loadが開始された際のイベント
    webView.ShouldStartLoad = delegate(UIWebView view, NSUrlRequest request, UIWebViewNavigationType navigationType){
        //ナビゲーションの種類によって処理を分岐する
        if (navigationType == UIWebViewNavigationType.LinkClicked){
            //リンクを選択した場合は、デフォルトのブラウザを開く
            UIApplication.SharedApplication.OpenUrl(request.Url);
            return false;
        }
        return true;
   }; 

【 Xamarin 記事一覧 】