有時候你會有自己的想法去安排手機上網頁的顯示,比方說往下拉會有個按鈕,中間是網頁文字,上面可能是廣告或圖片,全都放在一個UISrollView裡面,而且你希望不要分開scroll,而是整體一起拉,scroll在整個畫面上,橫亙整個廣告圖片文字按鈕,那你就會有這樣的需求。
self.webView.scrollView.scrollEnabled = NO;
注意到我這邊的寫法,我是將webView在xib內拉好,設定好Autolayout,在xib內,我將webView放在scrollView元件下,作為其subView。如果你是打算動態生成webView元件,那你記得要將這元件加到scrollView之中,這非常合理,因為這是你捲動畫面內容的其中一部分啊。
UIWebView *yourWebView; // please initialization by yourself
[self.scroll addSudview: yourWebView];
只是我是在xib內拉好,所以系統會知道那個IBOutlet的webView元件是Scroll view的subview。
到目前為止我們做了兩件事情:
再來的事情就是一些coding了,根據情況不同,有一些部分會不太一樣,主要順序是這樣:
改變的時機,就是web view讀取完資料的時候,請將你的View Controller遵守UIWebViewDelegate,我們要在讀取完時作剩下的工作:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@"Finished loading");
if (![webView isEqual:self.webView) { // 如果不是我的webView元件就跳回
return;
}
float totalHeight = 0; // 用來儲存總高度,等下要設定scroll view的高度
//[self.webView sizeToFit];
//NSString *heightString = [self.webContent stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"body\").offsetHeight;"];
CGRect frame = self.webView.frame;
frame.size.height = 1;
self.webView.frame = frame;
CGSize contentFrame = [webView sizeThatFits:CGSizeZero];
frame.size = contentFrame;
self.webView.frame = frame;
float webHeight = frame.size.height;
float imageHeight = self.webImageView.bounds.size.height;
totalHeight = webHeight + imageHeight + self.btn.bounds.size.height;
// 設定scroll view的內容高度
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width, totalHeight)];
// 設定按鈕位置
[self.btn setFrame:CGRectMake(28, self.webImageView.bounds.size.height + 13 + self.webContent.bounds.size.height, self.btn.bounds.size.width, self.btn.bounds.size.height)];
}
在我看的教學文章裡面,請大家注意到我程式碼中間有紅色、藍色和紫色的三行,那三行各有人使用,紅色那行sizeToFit有些人說無效果,有人說有效,他是會直接調整你的web view的尺寸,藍色那行是很多人會使用js語言得到高度,紫色這行是會回傳你內容高度,你選擇其中一種使用即可,看看哪行對你有效果。
另外,由於這篇文章是使用auto layout去做的,雖然跟官方文件提到的autolayout和scrollView混用的作法不一樣(不是mix也不是pure),因為最後還是設定了contentSize。
接下來,建立以下元件之間的constraints:
另一種Auto layout的調整方法
將UIWebView的高度constraint建立一個接口:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *webViewHeightConstraint;
然後在webViewDidFinishLoad:裡面重新設定他就可以了:
self.webViewHeightConstraint.constant = self.webView.scrollView.contentSize.height;
透過將webView的scroll view的contentSize高度來獲得真正的內容高度。這樣上面就不用使用sizeToFit這樣的方法了。
如果你的html string裡面有圖片,然後你有調整圖片,那你恐怕不能使用self.webView.scrollView.contentSize,因為他提供的是圖片原始尺寸下的高度,所以,你必須要透過javascript指令來獲取目前的高度:
self.webViewHeightConstraint.constant = [[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.height"]] floatValue];
預備動作
當你在用UIWebView時,你會發現呈現出來的結果也是可以拉動的,這是因為UIWebView本身裡面是有scroll特性在的,為了避免scroll混在一起,你要先把 UIWebView 本身的捲動功能關掉:self.webView.scrollView.scrollEnabled = NO;
注意到我這邊的寫法,我是將webView在xib內拉好,設定好Autolayout,在xib內,我將webView放在scrollView元件下,作為其subView。如果你是打算動態生成webView元件,那你記得要將這元件加到scrollView之中,這非常合理,因為這是你捲動畫面內容的其中一部分啊。
UIWebView *yourWebView; // please initialization by yourself
[self.scroll addSudview: yourWebView];
只是我是在xib內拉好,所以系統會知道那個IBOutlet的webView元件是Scroll view的subview。
到目前為止我們做了兩件事情:
- 關閉web view的scroll功能
- 將web view設定成scroll view的subview
Programming
接下來我打算作的事情是這樣,scroll view最上方是圖片,使用image view呈現,中間是網頁文字,就是web view的部份,最下面是一個button,在autolayout內我設定他和web view 之間有隔了13px(會特別提這個是有原因的)。再來的事情就是一些coding了,根據情況不同,有一些部分會不太一樣,主要順序是這樣:
- 在web view讀取完他要的資料之後,要開始改變web view和scroll view的尺寸。
- 將web view的尺寸拉開,讓他完整呈現他的內容。
- 根據web view尺寸的改變重新設定其他元件與其的相對位置。
改變的時機,就是web view讀取完資料的時候,請將你的View Controller遵守UIWebViewDelegate,我們要在讀取完時作剩下的工作:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@"Finished loading");
if (![webView isEqual:self.webView) { // 如果不是我的webView元件就跳回
return;
}
float totalHeight = 0; // 用來儲存總高度,等下要設定scroll view的高度
//[self.webView sizeToFit];
//NSString *heightString = [self.webContent stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"body\").offsetHeight;"];
CGRect frame = self.webView.frame;
frame.size.height = 1;
self.webView.frame = frame;
CGSize contentFrame = [webView sizeThatFits:CGSizeZero];
frame.size = contentFrame;
self.webView.frame = frame;
float webHeight = frame.size.height;
float imageHeight = self.webImageView.bounds.size.height;
totalHeight = webHeight + imageHeight + self.btn.bounds.size.height;
// 設定scroll view的內容高度
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width, totalHeight)];
// 設定按鈕位置
[self.btn setFrame:CGRectMake(28, self.webImageView.bounds.size.height + 13 + self.webContent.bounds.size.height, self.btn.bounds.size.width, self.btn.bounds.size.height)];
}
在我看的教學文章裡面,請大家注意到我程式碼中間有紅色、藍色和紫色的三行,那三行各有人使用,紅色那行sizeToFit有些人說無效果,有人說有效,他是會直接調整你的web view的尺寸,藍色那行是很多人會使用js語言得到高度,紫色這行是會回傳你內容高度,你選擇其中一種使用即可,看看哪行對你有效果。
另外,由於這篇文章是使用auto layout去做的,雖然跟官方文件提到的autolayout和scrollView混用的作法不一樣(不是mix也不是pure),因為最後還是設定了contentSize。
Auto Layout setup
順便一提Auto Layout的設定的部份,簡單說,你xib內你拉好一個scroll view,然後scroll view裡面放一個UIView作為容器,其他要放進scroll view的元件都放到這個UIView內,就叫他content view吧,這個content view是唯一的scroll view的subview。然後你把元件放到content view裡面去。接下來,建立以下元件之間的constraints:
- scroll view ----- scroll view的super view (四個邊)
- content view ----- scroll view (四個邊)
- content view內元件 ----- content view
另一種Auto layout的調整方法
將UIWebView的高度constraint建立一個接口:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *webViewHeightConstraint;
然後在webViewDidFinishLoad:裡面重新設定他就可以了:
self.webViewHeightConstraint.constant = self.webView.scrollView.contentSize.height;
透過將webView的scroll view的contentSize高度來獲得真正的內容高度。這樣上面就不用使用sizeToFit這樣的方法了。
如果你的html string裡面有圖片,然後你有調整圖片,那你恐怕不能使用self.webView.scrollView.contentSize,因為他提供的是圖片原始尺寸下的高度,所以,你必須要透過javascript指令來獲取目前的高度:
self.webViewHeightConstraint.constant = [[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.height"]] floatValue];
留言
張貼留言