UIWebView 使用要注意的几点
最近有客户希望将移动端统一使用HTML5来完成,在iOS端就要用到UIWebView。遇到了以下三个主要问题:
加载HTTPS页面
不像Safari可以弹出弹框问用户是否忽略证书,在UIWebView中只会得到一个空白页。由于UIWebView并没有提供HTTPS相关的接口,所以不能直接在UIWebView中进行操作。经过stackoverflow知道,原来可以先通过NSURLConnection通过HTTPS验证,然后再用UIWebView加载页面,这样就达到了想要的目的。
#pragma mark - Webview delegate- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authenticated);if (!_authenticated) {
_authenticated = NO;_urlConnection = [[NSURLCoNnection alloc] initWithRequest:_request delegate:self];
[_urlConnection start];
return NO;
}return YES;
}#pragma mark - NURLConnection delegate
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
NSLog(@"WebController Got auth challange via NSURLConnection");if ([challenge previousFailureCount] == 0)
{
_authenticated = YES;NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
} else
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
NSLog(@"WebController received response via NSURLConnection");// remake a webview call now that authentication has passed ok.
_authenticated = YES;[_web loadRequest:_request];
// Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
[_urlConnection cancel];
}// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
中文乱码
由于服务器端使用的编码是GBK,UIWebView默认的是UTF-8编码,导致加载时出现乱码。将UIWebView的loadRequest方法用loadData方法来代替,具体代码如下:
NSURL *url = [NSURL URLWithString:_address.text];
NSData *data = [NSData dataWithContentsOfURL:url];
[_web loadData:data MIMEType:@"text/html" textEncodingName:@"GBK" baseURL:url];
旋转自适应
当iOS设备从Portrait旋转为Landscape时,UIWebView的宽度只占屏幕的一半。发现是autoResize的相关参数没有进行设置,应该设置如下:
webview.scalesPageToFit = YES;
webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
又由于不同的Orientation,其缩放参数不一样,所以在旋转时应对scrollView的zoomScale进行设置,如下:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {NSLog(@"willRotateToInterfaceOrientation");
CGFloat ratioAspect = _web.bounds.size.width/_web.bounds.size.height;
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortraitUpsideDown:
case UIInterfaceOrientationPortrait:
// Going to Portrait mode
NSLog(@"Portrait mode");
for (UIScrollView *scroll in [_web subviews]) { //we get the scrollview
// Make sure it really is a scroll view and reset the zoom scale.
if ([scroll respondsToSelector:@selector(setZoomScale:)]){
scroll.minimumZoomScale = scroll.minimumZoomScale/ratioAspect;
scroll.maximumZoomScale = scroll.maximumZoomScale/ratioAspect;
[scroll setZoomScale:(scroll.zoomScale/ratioAspect) animated:YES];
}
}
break;
default:
// Going to Landscape mode
NSLog(@"Landscape mode");
for (UIScrollView *scroll in [_web subviews]) { //we get the scrollview
// Make sure it really is a scroll view and reset the zoom scale.
if ([scroll respondsToSelector:@selector(setZoomScale:)]){
scroll.minimumZoomScale = scroll.minimumZoomScale *ratioAspect;
scroll.maximumZoomScale = scroll.maximumZoomScale *ratioAspect;
[scroll setZoomScale:(scroll.zoomScale*ratioAspect) animated:YES];
}
}
break;
}
}
UIWebView 使用要注意的几点