前言
UIWebView是常用開發(fā)控件体斩,對(duì)于一些常用的設(shè)置是有必要記住或者記錄下來的适瓦。
這里特別說一下钉稍,對(duì)于一個(gè)工程中整個(gè)就是一個(gè)WebView的情況屠尊,你可以通過一些設(shè)置來使整個(gè)工程顯得接近于原生開發(fā)的APP,這樣你是有機(jī)會(huì)被審核通過的糜颠。
UIWebView使用的栗子
self.mywebView = [[UIWebView alloc] initWithFrame:CGRectMake(0,20, self.view.frame.size.width, (self.view.frame.size.height-20))];
[self.view addSubview:self.mywebView];
self.mywebView.scrollView.scrollEnabled = YES;
self.mywebView.delegate = self;
self.mywebView.opaque = NO;
self.mywebView.backgroundColor=[UIColor clearColor];//透明汹族,不會(huì)出現(xiàn)黑線
self.mywebView.scrollView.bounces =NO;
[self.mywebView loadRequest: [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
順便提一下WKWebView,不做深究
WKWebView是iOS8中推出的其兴,算是UIWebVeiw的升級(jí)版顶瞒。繼承自 UIView
WKWebView的特點(diǎn):
- 性能高,穩(wěn)定性好元旬,占用的內(nèi)存比較小榴徐,
- 支持JS交互
- 支持HTML5 新特性
- 可以添加進(jìn)度條(然并卵,不好用匀归,還是習(xí)慣第三方的)坑资。
- 支持內(nèi)建手勢(shì),
- 據(jù)說高達(dá)60fps的刷新頻率(不卡)
WKWebView的創(chuàng)建
- 導(dǎo)入Webkit這個(gè)類庫(kù)(WKWebVeiw包含在里面的)
- 遵守協(xié)議(一般前兩個(gè)就行啦穆端,第三個(gè)主要是與JS相關(guān)的東西袱贮,這個(gè)協(xié)議中包含一個(gè)必須實(shí)現(xiàn)的方法,這個(gè)方法是提高App與web端交互的關(guān)鍵体啰,它可以直接將接收到的JS腳本轉(zhuǎn)為OC或Swift對(duì)象--網(wǎng)上大神說的攒巍,我沒用過。)
<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>
創(chuàng)建個(gè)WebView的對(duì)象
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]]; [self.view addSubview:webView];
UIWebView常用設(shè)置和方法的使用
1.UIWebView中使用到定位的話狡赐,APP中的 info.plist中就要設(shè)置跟定位相關(guān)的屬性值窑业。
<key>NSLocationAlwaysUsageDescription</key>
<string>位置</string>
<key>NSLocationWhenInUseUsageDescription</key>
<true/>
2.設(shè)置頂部和底部沒有彈性效果,使單個(gè)web應(yīng)用更顯原生APP枕屉。
self.mywebView.scrollView.bounces =NO;
3.自動(dòng)對(duì)頁(yè)面進(jìn)行縮放以適應(yīng)屏幕
self.mywebView.scalespageToFit = YES;
4. 自動(dòng)檢測(cè)網(wǎng)頁(yè)上的電話號(hào)碼常柄,單擊可以撥打
self.mywebView.detectsPhoneNumbers = YES;
5. 回到Web頁(yè)面頂部
[self.mywebView stringByEvaluatingJavaScriptFromString:@"window.scrollTo(0,0);"];
6. 可以加載一個(gè)本地資源:
//第一種方法:
NSString* path = [[NSBundle mainBundle] pathForResource:name ofType:@"html" inDirectory:@"mobile"];//mobile是根目錄,name是文件名稱,html是文件類型
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]]; //加載本地文件
//第二種方法:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *filePath = [resourcePath stringByAppendingPathComponent:@"mobile.html"];
NSString *htmlstring=[[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[uiwebview loadHTMLString:htmlstring baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
只有使用loadRequest:加載網(wǎng)頁(yè),才能對(duì)之后的鏈接操作做goBack,goForward操作,即canGoBack,canGoForward才有可能返回YES.
使用loadHTMLString,loadData都不可以.
7. 加載百度編譯器編輯的HTML文本
******** 使用UIWebView 加載 HTML圖文文本 *********
//self.newsM.content為網(wǎng)絡(luò)返回的原始圖文信息西潘。
NSString *content = self.newsM.content;
[mywebView loadHTMLString:content baseURL:nil];
********* 使用UILabel加載 HTML文本 *********
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[orangeStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
//得到富文本后賦值給Label卷玉,再對(duì)Label設(shè)置字體顏色和字體大小,而不用在富文本的得到過程中設(shè)置喷市。
contentLabel.attributedText = attrStr;
contentLabel.textColor = GrayTextColor;
contentLabel.font = [UIFont systemFontOfSize:MEDIUM_FONT-1];
8. 導(dǎo)航
一個(gè)UIWebView類內(nèi)部會(huì)管理瀏覽器的導(dǎo)航動(dòng)作相种,通過goForward和GoBack的方法你可以控制前進(jìn)與后退動(dòng)作:
可以通過來判斷是否可以前進(jìn)或者后退
@property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
@property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
[webView goBack];
[webView goForward];
[webView reload]; //重載
[webView stopLoading]; //取消載入內(nèi)容
9. 根據(jù)導(dǎo)航類型參數(shù)可以得到請(qǐng)求發(fā)起的原因
//當(dāng)網(wǎng)頁(yè)視圖被指示載入內(nèi)容而得到通知應(yīng)該返回是,這樣會(huì)進(jìn)行加載通過導(dǎo)航類型參數(shù)可以得到請(qǐng)求發(fā)起的原因品姓,可以是以下任意值:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)reuqest navigationType:(UIWebViewNavigationType)navigationType;
{
/*
UIWebViewNavigationTypeLinkClicked
UIWebViewNavigationTypeFormSubmitted
UIWebViewNavigationTypeBackForward
UIWebViewNavigationTypeReload
UIWebViewNavigationTypeFormResubmitted
UIWebViewNavigationTypeOther
*/
return YES;
}
10.使用原生API在 OC中調(diào)用JS方法
與UIWebView進(jìn)行交互寝并,調(diào)用web頁(yè)面中的需要傳參的函數(shù)時(shí),參數(shù)需要帶單引號(hào)腹备,或者雙引號(hào)(雙引號(hào)需要進(jìn)行轉(zhuǎn)義在轉(zhuǎn)義字符前加\),在傳遞json字符串時(shí)不需要加單引號(hào)或雙引號(hào):
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *sendJsStr=[NSString stringWithFormat:@"openFile(\"%@\")",jsDocPathStr];
[webView stringByEvaluatingJavaScriptFromString:sendJsStr];
}
11.為webView添加背景圖片:
approvalWebView.backgroundColor=[UIColor clearColor];
approvalWebView.opaque=NO;//這句話很重要衬潦,webView是否是不透明的,no為透明 在webView下添加個(gè)imageView展示圖片就可以了
12.獲取webView頁(yè)面內(nèi)容信息:
NSString *docStr=[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];//獲取web頁(yè)面內(nèi)容信息植酥,此處獲取的是個(gè)json字符串
SBJsonParser *parserJson=[[[SBJsonParser alloc]init]autorelease];
NSDictionary *contentDic=[parserJson objectWithString:docStr];//將json字符串轉(zhuǎn)化為字典
13.將文件下載到本地址然后再用webView打開:
NSString *resourceDocPath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"Documents"]];
self.filePath = [resourceDocPath stringByAppendingPathComponent:[NSString stringWithFormat:@"maydoc%@",docType]];
NSData *attachmentData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:theUrl]];
[attachmentData writeToFile:filePath atomically:YES];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[attachmentWebView loadRequest:requestObj];
//刪除指定目錄下的文件
NSFileManager *magngerDoc=[NSFileManager defaultManager];
[magngerDoc removeItemAtPath:filePath error:nil];
14.根據(jù)內(nèi)容獲取UIWebView的高度:
有時(shí)候需要根據(jù)不同的內(nèi)容調(diào)整UIWebView的高度镀岛,以使UIWebView剛好裝下所有內(nèi)容,不用拖動(dòng)友驮,后面也不會(huì)留白漂羊。有兩種方式可根據(jù)加載內(nèi)容 獲取UIWebView的合適高度,但都需要在網(wǎng)頁(yè)內(nèi)容加載完成后才可以卸留,即需要在webViewDidFinishLoad回調(diào)中使用走越。
使用JavaScript
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
CGRect frame = webView.frame;
NSString *fitHeight = [webview stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];
frame.size.height = [fitHeight floatValue];
webView.frame = frame;
}
15.取消長(zhǎng)按webView上的鏈接彈出actionSheet的問題:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout = 'none';"];
}
16.處理webView展示txt文檔亂碼問題
NSData *attachmentData = [[NSData alloc]initWithContentsOfFile:@"xxxx"];
//txt分帶編碼和不帶編碼兩種,帶編碼的如UTF-8格式txt艾猜,不帶編碼的如ANSI格式txt
//不帶的买喧,可以依次嘗試GBK和GB18030編碼
NSString* aStr = [[NSString alloc] initWithData:attachmentData encoding:NSUTF8StringEncoding];
if (!aStr)
{
//用GBK進(jìn)行編碼
aStr=[[NSString alloc] initWithData:attachmentData encoding:0x80000632];
}
if (!aStr)
{
//用GBK編碼不行,再用GB18030編碼
aStr=[[NSString alloc] initWithData:attachmentData encoding:0x80000631];
}
//通過html語(yǔ)言進(jìn)行排版
NSString* responseStr = [NSString stringWithFormat:
@""
""
""
""
"%@"
"/pre>"
""
"",
aStr];
[self.mywebView loadHTMLString:responseStr baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
17.如何在OC中給JS傳參數(shù)捻悯,如何在OC中獲取到JS傳遞過來的參數(shù)
如果要實(shí)現(xiàn)這樣的JS和OC的數(shù)據(jù)交互匆赃,需要使用到一個(gè)第三方文件:WebViewJavascriptBridge
給web發(fā)消息
@property WebViewJavascriptBridge * bridge;
NSString * mystring = @"你好";
[_bridge callHandler:@"testJavascriptHandler" data:mystring responseCallback:^(id response) {
DMLog(@"KLKL%@",response);
}];
// testJavascriptHandler 為JS中的方法
接收到web發(fā)來的消息
@property WebViewJavascriptBridge * bridge;
_bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView handler:^(id data, WVJBResponseCallback responseCallback) {}];
//bridge注冊(cè)js回調(diào)方法
[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"JJJJJJJJGEXUN %@",data);
}];
// testObjcCallback 為JS中的方法
這里必須說一下,上述方法必須在 self.webView 初始化好并設(shè)置好代理后今缚,因?yàn)橐坏?self.webView.delegate =self; 的代理在上述代碼后設(shè)置算柳,那么 WebViewJavascriptBridge 就無(wú)法進(jìn)行回調(diào)了。
而且這個(gè) WebViewJavascriptBridge 會(huì)劫持掉 - (void)webViewDidFinishLoad:(UIWebView *)webView {}這個(gè)回調(diào)方法姓言,在當(dāng)前的VC中不會(huì)觸發(fā)web的這個(gè)回調(diào)方法瞬项。 所以需要在VC中用到webViewDidFinishLoad方法時(shí),應(yīng)在 WebViewJavascriptBridge.m中做設(shè)置何荚。
18. 如何消除Web中 Alert彈框中出現(xiàn)的網(wǎng)址
這里解決的方法是通過使用 WKWebView 的方法囱淋。runJavaScriptConfirmPanelWithMessage,WKWebView 和 UIWebView都繼承自 UIView餐塘,但是奇怪的是妥衣,我是用WKWebView 里面的方法解決了UIWebView的問題 。
類別的方式
@interface UIWebView (JavaScriptAlert)
- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame;
- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame;
- (NSString *) webView:(UIWebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(id)frame;
@end
@implementation UIWebView (JavaScriptAlert)
static BOOL status = NO;
static BOOL isEnd = NO;
- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame {
UIAlertView* customAlert = [[UIAlertView alloc] initWithTitle:nil
message:message
delegate:nil
cancelButtonTitle:@"確定"
otherButtonTitles:nil];
[customAlert show];
}
- (NSString *) webView:(UIWebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(id)frame {
return @"";
}
- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame {
UIAlertView *confirmDiag = [[UIAlertView alloc] initWithTitle:nil
message:message
delegate:self
cancelButtonTitle:@"取消"
otherButtonTitles:@"確定", nil];
[confirmDiag show];
CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 7.) {
//這是問題的關(guān)鍵,使用 while不斷的循環(huán)税手,阻塞代碼的執(zhí)行蜂筹,直到Alert被處理為止。
while (isEnd == NO) {
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];
}
}else
{
while (isEnd == NO && confirmDiag.superview != nil) {
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];
}
}
isEnd = NO;
return status;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
status = buttonIndex;
isEnd = YES;
}
@end
19. UIWebView在 iOS11中的使用芦倒。
UIWebView 在iOS 11上 當(dāng)頂部的 y值設(shè)為 0 時(shí)艺挪,是依然無(wú)法蓋住UIStatusBar區(qū)域的,但是滾動(dòng)時(shí)就會(huì)出現(xiàn)問題了兵扬。會(huì)出現(xiàn) UIStatusBar 背后可以看見內(nèi)容麻裳。
解決辦法:UIWebView 初始化的時(shí)候Frame里面的y值設(shè)置為 20,這樣就不會(huì)出現(xiàn)UIStatusBar和內(nèi)容重疊的問題了器钟。
20. 如何獲取UIWebview加載內(nèi)容如標(biāo)題等......
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
titleLabel.text = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
獲取所有html:NSString *lJs = @"document.documentElement.innerHTML";
獲取網(wǎng)頁(yè)title:NSString *lJs2 = @"document.title";
UIWebView *lWebView = [self getCurrentWebView];
NSString *lHtml1 = [lWebView stringByEvaluatingJavaScriptFromString:lJs];
NSString *lHtml2 = [lWebView stringByEvaluatingJavaScriptFromString:lJs2];
JavaScript獲取網(wǎng)頁(yè)信息總結(jié):
JavaScript獲取當(dāng)前頁(yè)面URL掂器、title等,具體怎么用就看自己了~
由于本站用了偽靜態(tài)俱箱,所以獲取不到文檔名.document.location.port;是獲取URL關(guān)聯(lián)的端口號(hào)碼国瓮,thisHash = document.location.hash;是獲取鏈接屬性中在井號(hào)“#”后面的分段。
thisURL = document.URL;
thisHREF = document.location.href;
thisSLoc = self.location.href;
thisDLoc = document.location;
thisTLoc = top.location.href;
thisPLoc = parent.document.location;
thisTHost = top.location.hostname;
thisHost = location.hostname;
thisTitle = document.title;
thisProtocol = document.location.protocol;
thisPort = document.location.port;
thisHash = document.location.hash;
thisSearch = document.location.search;
thisPathname = document.location.pathname;
thisHtml = document.documentElement.innerHTML;
thisBodyText = document.documentElement.innerText;//獲取網(wǎng)頁(yè)內(nèi)容文字
thisBodyText = document.body.innerText;//獲取網(wǎng)頁(yè)內(nèi)容文字
小結(jié)
會(huì)持續(xù)更新......