UIWebView学习笔记

2019-11-02 04:02 来源:未知

UIWebView学习笔记

1. iOS 禁止使用webView加载网页的长按现身'拷贝'事件

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}

2. iOS webView长按图片,不现身'拷贝'(iOS9暗中认可就是这种功用)

2.1 准备好JS文件

// js文件,如:acepack_details.js
function setImageClickFunction(){
    var imgs = document.getElementsByTagName("img");
    for (var i=0;i<imgs.length;i++){
        imgs[i].style.webkitUserSelect='none';
    }
}

2.2 注入JS

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

3. webView作为tableView的tableHeaderView

  • 在webView的回调方法里,必供给重新载入参数tableView的tableHeaderView,不然会合世奇怪的标题。
-(void)webViewDidFinishLoad:(UIWebView *)webView {
    // 获取到webview的高度
    CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    self.webView.frame = CGRectMake(self.webView.frame.origin.x, self.webView.frame.origin.y, ScreenWidth, height);
    // 一定要重新设置tableView的tableHeaderView,否则会出现意想不到的问题。
    [self tableView].tableHeaderView = self.webView;
}

4. 替换webView中的img标签的图样

  • 采取场景
    • 收获页面中具有图片,图片浏览器
    • 非WIFI情形下,加载本地图片
- (NSString *)replaceImageUrl:(NSString *) content {
    // 匹配<img>标签
    NSString *urlPattern = @"<img[^>]+?src=["']?([^>'"]+)["']?";
    NSError *error = [NSError new];
    NSString *tmp = content;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlPattern options:NSRegularExpressionCaseInsensitive error:&error ];
    // match 这块内容非常强大
    NSUInteger count =[regex numberOfMatchesInString:content options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, [content length])];// 匹配到的次数
    UIImage *img = [UIImage imageNamed:@"icon_app"];
    // 用网络图片替换webView上显示的图片
    NSString *tmpStr = @"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png";
    // 用本地图片替换webView上显示的图片
    tmpStr = [self htmlForJPGImage:img];
    if(count > 0) {
        NSArray* matches = [regex matchesInString:content options:NSMatchingReportCompletion range:NSMakeRange(0, [content length])];
        for (NSTextCheckingResult *match in matches) {
            NSInteger count = [match numberOfRanges]; // 匹配项
            for(NSInteger index = 0;index < count;index++){
                NSRange halfRange = [match rangeAtIndex:index];
                if (index == 1) {
                    // 图片的src属性值
                    NSString *urlStr = [content substringWithRange:halfRange];
                    NSLog(@"=%@=",urlStr);
                    // 保存图片URL
                    [self.imgSrcArrayM addObject:[content substringWithRange:halfRange]];
                    // 替换src属性值
                    tmp = [tmp stringByReplacingOccurrencesOfString:urlStr withString: tmpStr];
                }
            }
        }
    }
    return tmp;
}

// 编码图片
- (NSString *)htmlForJPGImage:(UIImage *)image {
    NSData *imageData = UIImageJPEGRepresentation(image,1.0);
    NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
    return imageSource;
}

5. webView注入JS代码

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

6. webView执行JS代码

// 调用JS里的setImageClickFunction()函数
[self.webView stringByEvaluatingJavaScriptFromString:@"setImageClickFunction()"];

7. webView中的图片点击事件

7.1 准备好JS文件

// js文件,如:acepack_details.js
function setImageClickFunction(){
    // 取出所有的img标签
    var imgs = document.getElementsByTagName("img");
    for (var i=0;i<imgs.length;i++){
        var src = imgs[i].src;
        // 绑定事件
        imgs[i].setAttribute("onClick","clickme(src)");
    }
}

function clickme(imagesrc){
    var url="ClickImage:"+imagesrc;
    document.location = url;
}

7.2 注入JS

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

7.3 webView诉求回调里,实行JS

// 调用JS里的setImageClickFunction()函数
[self.webView stringByEvaluatingJavaScriptFromString:@"setImageClickFunction()"];

7.4 拦截央求,管理图片的单击事件

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)_request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *requestString = [[_request URL] absoluteString];
    NSString *prefix = @"clickimage:";
    if ([requestString hasPrefix:prefix]) {
        DDLogVerbose(@"%@", requestString);
        NSUInteger index = 0;
        NSRange range = [requestString rangeOfString:prefix];
        if (range.location != NSNotFound) {
            NSString *tmpSrc = [requestString substringFromIndex:(range.location + range.length)];
            index = [self.imgSrcArrayM indexOfObject:tmpSrc];
        }
        // 显示图片浏览器
        [self networkImageShow:index];
    }
    return YES;
}

8. 长按webView上的图片,保存

8.1 注入JS

static NSString* const kTouchJavaScriptString=
@"document.ontouchstart=function(event){
x=event.targetTouches[0].clientX;
y=event.targetTouches[0].clientY;
document.location="myweb:touch:start:"+x+":"+y;};
document.ontouchmove=function(event){
x=event.targetTouches[0].clientX;
y=event.targetTouches[0].clientY;
document.location="myweb:touch:move:"+x+":"+y;};
document.ontouchcancel=function(event){
document.location="myweb:touch:cancel";};
document.ontouchend=function(event){
document.location="myweb:touch:end";};";
[self.webView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];

8.2 管理点击UIWebView上面的图样

#pragma mark - 处理点击UIWebView上面的图片
- (BOOL)handleWebViewClickImageWithUrl:(NSString *)url{
    NSString *requestString = url;
    NSArray *components = [requestString componentsSeparatedByString:@":"];
    if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
                                   isEqualToString:@"myweb"]) {
        if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"]) {
            //NSLog(@"you are touching!");
            //NSTimeInterval delaytime = Delaytime;
            if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"]) {
                /*
                 @需延时判断是否响应页面内的js...
                 */
                _gesState = GESTURE_STATE_START;
                NSLog(@"touch start!");
                float ptX = [[components objectAtIndex:3]floatValue];
                float ptY = [[components objectAtIndex:4]floatValue];
                NSLog(@"touch point (%f, %f)", ptX, ptY);
                NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY];
                NSString *tagName = [self.webView stringByEvaluatingJavaScriptFromString:js];
                _imgURL = nil;
                if ([tagName isEqualToString:@"IMG"]) {
                    _imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
                }
                if (_imgURL) {
                    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleLongTouch) userInfo:nil repeats:NO];
                }
            }
            else if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"move"])
            {
                //**如果touch动作是滑动,则取消hanleLongTouch动作**//
                _gesState = GESTURE_STATE_MOVE;
                NSLog(@"you are move");
            }
            else if ([(NSString *)[components objectAtIndex:2]isEqualToString:@"end"]) {
                [_timer invalidate];
                _timer = nil;
                _gesState = GESTURE_STATE_END;
                NSLog(@"touch end");
            }
        }
        return NO;
    }
    return YES;
}
// 处理长按事件
- (void)handleLongTouch {
    NSLog(@"%@", _imgURL);
    if (_imgURL && _gesState == GESTURE_STATE_START) {
        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"保存图片", nil];
        sheet.cancelButtonIndex = sheet.numberOfButtons - 1;
        [sheet showInView:[UIApplication sharedApplication].keyWindow];
    }
}
// 弹出对话框
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (actionSheet.numberOfButtons - 1 == buttonIndex) return;
    NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex];
    if ([title isEqualToString:@"保存图片"]) {
        if (_imgURL) {
            NSLog(@"imgurl = %@", _imgURL);
        }
        NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:_imgURL];
        NSLog(@"image url=%@", urlToSave);
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlToSave]];
        UIImage *image = [UIImage imageWithData:data];
        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
}
// 回调
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error) {
        NSLog(@"Error");
    } else {
        NSLog(@"OK");
    }
}

9. webView缓存

9.1 缓存的含义

  1. webView日常是加载UI相比较复杂靓丽、可变、iOS原生控件不易于实现的分界面,所以网页的要素日常都很复杂,对远在GPTiguanS情况下的顾客来说,流量是个大题材,所以供给缓存!
  2. 当客户处于断网状态下时,为了防止客商走入空白页面,应该把上次曾经加载过的页面呈现给客商!
  3. webView的须要日常都以GET,POST诉求日常是发大批量数据给服务器管理(变动性相当的大),因而常常只对GET央求举办缓存,而不对POST央浼实行缓存。

9.2 为何能够举办缓存?

  • NSU奥迪Q7LCache在各类UIWebView的的NSUPRADOLRequest央求中都会被调用。
  • iOS 5早先:只扶植内部存款和储蓄器缓存;从iOS 5初阶:同不常候扶持内部存款和储蓄器缓存和硬盘缓存。

9.3 怎么产生缓存?

  • iOS设备上NSU昂科威LCache私下认可只能进展内部存款和储蓄器缓存。能够透过子类化NSU本田CR-VLCache来达成自定义的本子进而实现在DISK上缓存内容。
  • 供给重写cachedResponseForRequest,这一个会在乞求发送前会被调用,从当中大家能够看清是还是不是针对此NSURAV4LRequest再次回到本地数据。
  • 假如本地未有缓存就调用上边那条语句:return [super cachedResponseForRequest:request];

9.4 NSU奥德赛LCache常用艺术

  1. 全局缓存对象
NSURLCache *cache = [NSURLCache sharedURLCache]; 
  1. 设置内部存款和储蓄器缓存的最大体量(字节为单位,默以为512KB)
-(void)setMemoryCapacity:(NSUInteger)memoryCapacity;
  1. 安装硬盘缓存的最大体积(字节为单位,默以为10M)
-(void)setDiskCapacity:(NSUInteger)diskCapacity;
  1. 赢得某个乞求的缓存
-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; ```
5. 清除某个请求的缓存
``` objc
-(void)removeCachedResponseForRequest:(NSURLRequest *)request;
  1. 消逝全部的缓存
-(void)removeAllCachedResponses;

9.5 设置NSURubiconLRequest缓存战略

  • NSUSportageLRequestUseProtocolCachePolicy // 暗中同意的缓存计谋(决定于情商)
  • NSUPAJEROLRequestReloadIgnoringLocalCacheData // 忽视缓存,重新央求
  • NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现
  • NSUPRADOLRequestReloadIgnoringCacheData = NSU纳瓦拉LRequestReloadIgnoringLocalCacheData // 忽视缓存,重新必要
  • NSU锐界LRequestReturnCacheDataElseLoad // 有缓存就用缓存,未有缓存就再也央浼
  • NSU奥迪Q5LRequestReturnCacheDataDontLoad // 有缓存就用缓存,未有缓存就不发伏乞,当做伏乞出错管理(用于离线情势)
  • NSURLRequestReloadRevalidatingCacheData // 未实现
TAG标签:
版权声明:本文由银河国际点击登录发布于银河国际点击登录,转载请注明出处:UIWebView学习笔记