UIWebView練習作業

作業目標:http://www.youtube.com/watch?v=azplcMbuoQ4&feature=youtu.be
練習檔案:homework0831

先介紹一下UIWebView

UIWebView的資料來源主要有三者:

  1. 本機上的HTML字串
  2. 本機上的資料 + MIME type
  3. 遠端的URL

這邊有中文的介紹:http://www.inside.com.tw/2010/03/14/cs193p-lecture-12

作業練習開始

首先我先拉出storyboard
螢幕快照 2013-09-04 下午11.30.34

然後我練習使用程式去產生UINavigationController,這是在AppDelegate.m裡

然後ViewController.h裡在viewDidLoad時初始化一些頁面數值

實作按鈕按下時的動作

接下來做WebViewController.m裡的內容,
在這邊我弄了一個下載進度的物件叫作UIActivityIndicatorView
這部份首先要先在- (void)viewDidLoad裡初始化載入效果

然後加上下面兩段程式碼

然後在實做UIWebView的Delegate去設定載入畫面
[UIApplication sharedApplication].networkActivityIndicatorVisible這個是在上方指示列的圈圈圖示

遇到問題(高手幫忙看3Q)

然後其實接下來這一點問題我弄了非常久~ 就是,在從上一頁傳來網址時,
也會執行到
-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
所以會必須去判斷現在是使用者點擊的link,或是是從上頁傳來的指令

為了這個需求,我用了幾個方式,但都有問題,包括現在的其實也有,但因為實在搞太久~
所以就先這樣@@等老師公布他的作法後再來補修正

我總用試了這些方式

  1. 使用一個BOOL去判別,只有第一次loading頁面時不做跳頁呼叫,然後當webViewDidFinishLoad時將BOOL改為NO
    問題點:有某些頁面會有js檔案,當頁面全部載入完成後,執行js後,就又會再第二次讀取網路資料,此時頁面就會莫名的突然回到第一頁然後顯示網址。(例如:我的部落格http://claire-chang.com)
  2. 使用NSConnection(http://stackoverflow.com/questions/9475768/loading-nsdata-into-a-uiwebview)
    這是一個異想天開(?)的想法,我想說,第一次loading時用NSConnection去讀html,然後用loadHTMLString:baseURL:來顯示在畫面上。結果html成功的載下來了,但是不知為何WebView呈現一片空白。
    在網路上查了一下,似乎是因為<scripe>標籤的關係(不確定)
  3. 現在版本的方式:偵測使用者點擊事件,當使用者點擊時,判斷現在是使用者點擊事件,下一次的網頁讀取便會跳頁。
    不過這種方式也有問題,同第一點,不過狀況會變成若頁面尚未載入完,使用者就點擊非link的地方時,js呼叫讀取網頁時,就會跳回第一頁,然後網址顯示為js呼叫的頁面網址= =

也是因為這樣子,我才會去製作下載畫面,想說在未loading完前不讓使用者按下WebView,
結果因為畫面會先loading完成、然後才自動因js而去呼叫另一個網址。
中間還是會有使用者可以點擊畫面的時間點。

我總覺得UIWebView應該有個東西是可以直接判別是否是使用者呼叫的,
觀察過dataDetectorTypes的值,卻似乎不是~orz
有知道的人麻煩幫解惑吧~3Q!
ps:若想試有js會在loading完成後再次loading的狀況,請把網址設為我的部落格http://claire-chang.com

因為我是用第三種方式,所以我對WebView增加了碰觸事件的偵聽
首先在- (void)viewDidLoad設定碰觸事件監聽

然後要實作UIGestureRecognizerDelegate

上面這個一定要加,這樣子handleTapFrom:才會被呼叫到
然後當按到時將bool值改成YES

當讀取網頁且isClick是YES時就跳回第一頁

這時再回去ViewController.m增加接收的方法