以前にUIWebView+AngularJSで軽く動作させてみましたが、
今回は画面遷移をやってみようと思います。
構成としては
で、トップメニュー画面とサブ画面がUIWebView上のHTMLで表示、
メイン画面を通常のViewで実装してみたいと思います。
・イメージ図
独自URLスキームの作成
実装するアプリ専用のURLスキームを作成し、そのURLスキームで
リクエストが来た場合のみ処理を行うようにしたいと思います。
URLスキームとは
URLスキームはhttp://hogehoge
のhttpを差します
前回WebViewが新たなフレームをロードする時にハンドリングする
メソッドをオーバーライドしました
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
return true
}
今回はここでNSURLRequest
からURLを取得し、作成する独自スキームであれば 画面遷移を行うようにしたいと思います。
作成するURLスキームはsample
として進めていきます
sample
をURLスキームとした例は以下のようになります
sample://hogehoge/fuga/index.html
独自URLスキームのハンドリング
func webView
を独自URLスキームを判定する為に以下のような内容で編集します
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let url = request.URL!.absoluteString
if url.hasPrefix("sample://") {
// 何かしらの処理
return false
}
return true
}
request.URL!.absoluteString
でリクエストURLのフルパスを取得しています
次の行のif url.hasPrefix("sample://")
で独自URLスキームかどうかの判定をしています
画面遷移(トップメニュー画面→サブ画面)
トップメニュー画面からサブ画面の画面遷移を実装してみたいと思います。
別のHTMLをロードしてほしいリクエストURLをsample://html/XXXX
とします
XXXにはロードしたいhtml名を設定します。
例) menu.htmlからsub.htmlを表示させたい時
sample://html/sub
URLはサンプル用です
html名を与えたらhtmlをロードしてくれるメソッドを作成します
private func locationChanged(res :String) {
let url = NSBundle.mainBundle().pathForResource(res, ofType: "html");
let reqURL = NSURL(string: url!)
let req = NSURLRequest(URL: reqURL!)
webView.loadRequest(req)
}
↑では引数のres
の名前+拡張子がhtml
のリソースパスを取得し、
リソースパスをリクエストURLに変換しUIWebViewにロードさせています
作成したメソッドを使ってfunc webView
を以下のように修正します
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let url = request.URL!.absoluteString
if url.hasPrefix("sample://") {
if url == "sample://html/sub” { ・・★
locationChanged("sub")
}
return false
}
return true
}
★リクエストURLがsample://html/sub
の場合locationChanged
に
引数"sub"を渡して呼び出しています
<!doctype html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
<div>
<form ng-controller="myController">
<lable>Link:</label>
<button ng-click="onClick()">send</button>
</form>
</div>
</body>
<script>
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
// setting click listener
$scope.onClick = function() {
location.href = "sample://html/sub";・・★
};
}]);
</script>
</html>
★前回作成したindex.htmlでのボタン押したリンク先をサブ画面に変更しています
<!doctype html>
<html>
<head>
<title>Sub Screen</title>
</head>
<body>
<h2>Sub Screen</h2>
</body>
</html>
サブ画面はいたって単純でSub Screenと表示するだけです
↓画面遷移の様子
画面遷移(トップメニュー画面→メイン画面)
トップメニュー画面からメイン画面への遷移ですが、
こちらも特定のリクエストURLの場合にハンドリングするのは変わらず、
ハンドリングしたら別UIViewControllerへ遷移させます
別UIViewControllerへ遷移する為のメソッドを作成します
// Screen transition MainViewController.
private func startMainView() {
let mainViewController = self.storyboard!
.instantiateViewControllerWithIdentifier("mainview")
self.presentViewController(mainViewController, animated: false, completion: nil)
}
↑ではストーリーボード上の遷移先のStoryboard IDmainview
を取得し
presentViewController
で画面遷移させています
Storyboard IDのつけ方
今度はsample://html/sub
のリクエストURLが来たら
startMainView
を呼ぶようにfunc webView
を変更します
// handling event
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let url = request.URL!.absoluteString
if url.hasPrefix("sample://") {
if url == "sample://html/sub" {
locationChanged("sub")
} else if url == "sample://html/main" {・・★
startMainView()
}
return false
}
return true
}
また、menu.htmlもメイン画面へのリンクボタンを追加します
<!doctype html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
<div>
<form ng-controller="myController">
<lable>Link: Sub</label>
<button ng-click="onClickSub()">send</button>
<lable>Link: MainView</label>
<button ng-click="onClickMain()">go</button>
</form>
</div>
</body>
<script>
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
// setting click listener
$scope.onClickSub = function() {
location.href = "sample://html/sub";
};
// setting click listener
$scope.onClickMain = function() {・・★
location.href = "sample://html/main";
};
}]);
</script>
</html>
↓実行結果