webView中使用内嵌html的总结

本文总结了在iOS开发中使用UIWebView加载内嵌HTML页面的方法,包括如何导入HTML文件、替换JSON数据、OC与JS交互、处理图片以及处理页面重定向等关键步骤。通过实例代码详细讲解了字符串替换、正则表达式获取图片URL以及处理用户点击图片的响应等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在开发项目时,用到了UIWebView,还用到了内嵌的html页面,用到了很多的js方面的东西,oc与js进行交互,同时还用到了重定向原理,这里做一下总结:

(1)使用到的内嵌html页面,我们这里要导入html页面到工程中。由于返回的json数据里包含有网页格式,我们需要对关键字替换

//数据解析

-(void)analyzeJSONData:(NSDictionary *)jsonDic{

    newsDetailInfo=[Tools parseForNewsDetailInfoJSONString:jsonDic];

    [newsDetailInfo retain];

    if (newsDetailInfo.appInfo!=nil) {

        newsAppInfo=[Tools parseForNewsAppInfoJSONString:newsDetailInfo.appInfo];

        [newsAppInfo retain];

        if (IS_PHONE) {

            [self replaceJSONDataWithHTML:STRATEGY_DETAIL_FILENAME];

        }else{

            [self replaceJSONDataWithHTML:STRATEGY_DETAIL_FILENAME_IPD];

        }

    }else{

        if (IS_PHONE) {

            [self replaceJSONDataWithHTML:NEWS_DETAIL_FILENAME];

        }else{

            [self replaceJSONDataWithHTML:NEWS_DETAIL_FILENAME_IPAD];

        }

        

    }

}

//替换

-(void)replaceJSONDataWithHTML:(NSString *)fileName{

    NSError *error;

    _fileContents=[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:@"html"] encoding:NSUTF8StringEncoding error:&error];

    NSString *resultHTMLString;

    resultHTMLString=[_fileContents stringByReplacingOccurrencesOfString:@"[title]" withString:newsDetailInfo.title];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[modifyTime]" withString:newsDetailInfo.modifyTime];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[commentCount]" withString:[NSString stringWithFormat:@"%d",newsDetailInfo.commentCount]];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[author]" withString:newsDetailInfo.author];

    if (pageNum==1) {

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[summary]" withString:newsDetailInfo.summary];

        contentString=newsDetailInfo.summary;

    }else{

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[summary]" withString:_remainResponseString];

    }

    if ([fileName isEqualToString:STRATEGY_DETAIL_FILENAME] || [fileName isEqualToString:STRATEGY_DETAIL_FILENAME_IPD]) {

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[icon]" withString:newsAppInfo.iconURL];

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[appName]" withString:newsAppInfo.name];

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[version]" withString:newsAppInfo.version];

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[size]" withString:newsAppInfo.size];

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[language]" withString:newsAppInfo.language];

    }

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@" " withString:@""];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img" withString:@"<br><img"];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<embed" withString:@"<br><embed"];

    if (IS_PHONE) {

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"width=" withString:@"width2="];

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"height=" withString:@"height2="];

    }

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\n" withString:@" "];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\t" withString:@" "];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<br />" withString:@" "];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<br>" withString:@" "];

    for (NSString *str in sepLineArray) {

        resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:str withString:@""];

    }

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img src=\"\" alt=\"\" /> " withString:@""];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img alt=\"\" src=\"\" height2=\"18\" width2=\"597\" />" withString:@""];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\"ID\":id,\"isnotdeletealink\":iol,\"pageNum\":pagenum" withString:@"\"ID\":newsInfoID,\"isnotdeletealink\":\"false\",\"pageNum\":pagenum"];

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"newsInfoID" withString:[NSString stringWithFormat:@"%d",newsInfoID]];

    [_contentWebView loadHTMLString:resultHTMLString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];

}


(2)在上面的替换中,需要特别注意的是

    resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\"ID\":id,\"isnotdeletealink\":iol,\"pageNum\":pagenum" withString:@"\"ID\":newsInfoID,\"isnotdeletealink\":\"false\",\"pageNum\":pagenum"];

这里主要是后面做网页加载下一页时用ajax加载处理,这里先暂时不讲

(3)在获取图片的过程中,我们用到了正则表达式获取

-(NSMutableArray *)getWebViewPictureUrlString{

    NSString * JsString = @"document.documentElement.innerHTML";

    NSString * str = [_contentWebView stringByEvaluatingJavaScriptFromString:JsString];

    NSString *regexString  = @"<img [^>]*/?>";

    NSArray *matchArray=[str componentsMatchedByRegex:regexString];

    NSMutableArray *resultArr = [[NSMutableArray new]autorelease];

    for (NSString *imgString in matchArray) {

        NSArray *stringArr=[imgString componentsSeparatedByString:@"\""];

        for (NSString *string in stringArr) {

            if ([string rangeOfString:@"http://"].location!=NSNotFound){

                if([string rangeOfString:@"Upload"].location!=NSNotFound || [string rangeOfString:@"smtpfbackend"].location!=NSNotFound) {

                    [resultArr addObject:string];

                }

            }

        }

    }

    return resultArr;

}


(4)点击某一张图片时,我们要获取到是哪张图片,同样需要正则表达式

//点击某张图片

-(void)imageTappedInWebView:(UITapGestureRecognizer *)sender{

    self.imageURLArray=[self getWebViewPictureUrlString];

    CGPoint pt = [sender locationInView:_contentWebView];

    NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];

    NSString *urlToSave = [_contentWebView stringByEvaluatingJavaScriptFromString:imgURL];

    if ([urlToSave rangeOfString:@"icon"].location==NSNotFound){

        if (urlToSave.length > 0) {

            for (int i = 0; i < [self.imageURLArray count]; ++i) {

                if ([[self.imageURLArray objectAtIndex:i] isEqualToString:urlToSave]) {

                    currentIndex=i;

//                    [self showImageTapped:sender AtIndex:currentIndex];   // 2014.7.15

                    break;

                }

            }

        }

    }

}

(5)重定向用的太多了,在webView的代理响应里头很杂乱,值得注意的是loadnextpage这个重定向

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{

    NSString *requestString=[[[request URL]absoluteString]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    if ([requestString hasPrefix:@"testapp://"]) {

        [self entryIntoGameAppDetail];

    }

    if ([requestString hasPrefix:@"setting:"]) {

        NSArray *components=[requestString componentsSeparatedByString:@":"];

        [self setTappedRectFromTappedImage:components];

        [self showImageTapped:nil AtIndex:currentIndex];

    }

    if ([requestString hasPrefix:@"testappnewsid:"]) {

        NSArray *components=[requestString componentsSeparatedByString:@":"];

        NSInteger newsId=[[components objectAtIndex:1]integerValue];

        [self entryIntoGameAppDetail:newsId];

    }

    if ([requestString hasPrefix:@"loadnextpage://"]) {

        if(IS_PHONE){

            NSInteger preIndex=[self.imageURLArray count];

            self.imageURLArray=[self getWebViewPictureUrlString];  //下一次请求后 图片会增多

            dispatch_queue_t queue=dispatch_queue_create("imagedownloadNextPage", NULL);

            dispatch_async(queue, ^{

                [self asynRequestForImageArr:self.imageURLArray fromIndex:preIndex];

            });

        }

    }

    if ([requestString hasPrefix:@"returnsetting:"]) {

        [self removeImageAnimationWithCGRectString:requestString];

    }

    return YES;

}

在html页面中,这里主要是定义协议,写js方法,可以对照看是对应哪个协议的重定向

        <script type="text/javascript" src="jquery-1.8.0.min.js"></script>

        <script type="text/javascript">

                var id="",iol="",pagenum=2,

                fact=true,essen=true;

                function entryIntoGameAppDetail(){

                    document.location = 'testapp://';

                }

                function loadata()

                {

             

                    totalheight = parseFloat($(window).height()) + parseFloat($(window).scrollTop());

             

                    var kk={"ID":id,"isnotdeletealink":iol,"pageNum":pagenum,"type":"pageData","version":510};

                    if ($(document).height() <= totalheight)

                    {

                        if(fact==true){

                            fact=false;

                            $.ajax({

                                   type: 'POST',

                                   url: "http://api.ios.d.cn/api-news/NewsInfoByJson.ashx",

                                   data: kk,

                                   dataType: 'html',

                                   success: function (data) {

                                        document.location='loadnextpage://';

                                        fact=true;

                                        $("div.body").append(data);

                                        pagenum++;

                                        set();

                                   },

                                   error: function (XMLHttpRequest, textStatus, errorThrown) {

                                        alert(errorThrown);

                                   }

                            });

             

             }

             }

             }

             $(window).scroll( function() {

                              loadata();

                              });

   

            function set(){

                $("body img").unbind("click");

                     $("body img").bind("click",function(e){

                                        var y=$(this).offset().top,

                                        x=$(this).offset().left,

                                        w=$(this).width(),

                                        h=$(this).height();

                                        document.location = 'setting:'+x+':'+y+':'+w+':'+h;

                     })

            }

        

        function reset(e){

            e="\""+e+"\"";

            var that=$("img[src="+e+"]");

            var y=that.offset().top,

            x=that.offset().left,

            w=that.width(),

            h=that.height();

            document.location ='returnsetting:'+x+':'+y+':'+w+':'+h;

        }

        set();


 function showAlert() {

    alert($);

}


         </script>

这里reset(e)是对应的获取某一张链接图片在webView中的originx,originy,width,height,以便做图片的动画效果处理,set()是点击某一张图片时,返回对应的在 webView中的originx,originy,width,height。webView滚动的过程中,采用ajax进行加载下一页接口数据。

(6)做图片的点开和缩回动画,这里没写好,效果应该相差不多

-(void)showImageAnimation:(UIImage *)tappedImage atIndex:(NSInteger)index{

    NSMutableArray *imageRectArr=[self getTappedRectForTappedImage];

    float originX=[imageRectArr[0]floatValue]+6;

    float originY=[imageRectArr[1]floatValue]-_contentWebView.scrollView.contentOffset.y+6;

    float width=[imageRectArr[2]floatValue];

    float height=[imageRectArr[3]floatValue];

    CGRect imageRect=CGRectMake(originX, originY, width, height);

    [_imageScrollView tappedSelectedImageIndex:index beforeAnimation:imageRect];


    UIColor *bgColor=_imageScrollView.backgroundColor;

    [_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0]];


    [UIView animateWithDuration:0.25 animations:^{

        [_imageScrollView tappedSelectedImageIndex:index animation:YES];

        [[MainVC sharedMe].view addSubview:_imageScrollView];

        UIColor *bgColor=_imageScrollView.backgroundColor;

        [_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:1]];

    } completion:^(BOOL finished){

    }];

}


-(void)removeImageAnimationWithCGRectString:(NSString *)rectStr{

    NSArray *components=[rectStr componentsSeparatedByString:@":"];

    float originX=[components[1] floatValue]+6;

    float originY=[components[2] floatValue]+6;

    float width=[components[3] floatValue];

    float height=[components[4] floatValue];

    float scrollToY=originY-(_contentWebView.frame.size.height/2-height/2);

    if (originY<_contentWebView.scrollView.contentOffset.y-height || originY>_contentWebView.scrollView.contentOffset.y+_contentWebView.frame.size.height) {

        [_contentWebView.scrollView scrollRectToVisible:CGRectMake(0, scrollToY, _contentWebView.frame.size.width, _contentWebView.frame.size.height) animated:NO];

    }

    CGRect imgInScrollViewRect=[_imageScrollView setImageFrame:[imageDownloaded objectAtIndex:removeImageIndex]];  //scrollViewimagerect

    CGRect imageRect=CGRectMake(originX, originY-_contentWebView.scrollView.contentOffset.y, width, height);  //webview中的imgrect


    [UIView beginAnimations:@"newsimage_disappear_Animation" context:nil];

    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    [UIView setAnimationDuration:0.3];

    [UIView setAnimationDelegate:self];

    float scale1=imageRect.size.width/imgInScrollViewRect.size.width;

    float scale2=imageRect.size.height/imgInScrollViewRect.size.height;

    MNZoomScrollView *view=(MNZoomScrollView *)[_imageScrollView subviews][removeImageIndex];

    UIImageView *imgView=(UIImageView *)[view subviews][0];

    imgView.frame=imgInScrollViewRect;

    UIImage *image=[imageDownloaded objectAtIndex:removeImageIndex];

    imgView.image=image;

    CGAffineTransform currentTransform=imgView.transform;

    CGAffineTransform newTransform=CGAffineTransformScale(currentTransform, scale1, scale2);

    [imgView setTransform:newTransform];

    imgView.frame=imageRect;

    

    UIColor *bgColor=_imageScrollView.backgroundColor;

    [_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0.5]];

    

    [UIView setAnimationDidStopSelector:@selector(animationStopRomove)];

    [UIView commitAnimations];

}


-(void)animationStopRomove{

    MNZoomScrollView *view=(MNZoomScrollView *)[_imageScrollView subviews][removeImageIndex];

    UIImage *image=[imageDownloaded objectAtIndex:removeImageIndex];

    CGRect imgRect=[_imageScrollView setImageFrame:image];

    UIImageView *imgView=(UIImageView *)[view subviews][0];

    [imgView setFrame:imgRect];

    UIColor *bgColor=_imageScrollView.backgroundColor;

    [_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0]];

    [_imageScrollView removeFromSuperview];

}

(7)由于图片没有id,没办法从网页通过js抓取图片,只有多线程异步加载


- (void)webViewDidFinishLoad:(UIWebView *)webView{

    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];

    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];//自己添加的,原文没有提到。

    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];//自己添加的,原文没有提到。

    [[NSUserDefaults standardUserDefaults] synchronize];

    

    if (IS_PHONE) {

        self.imageURLArray=[[NSMutableArray alloc]initWithArray:[self getWebViewPictureUrlString]];

        dispatch_queue_t queue=dispatch_queue_create("imagedownload", NULL);

        dispatch_async(queue, ^{

            [self asynRequestForImageArr:self.imageURLArray fromIndex:0];

        });

    }

    

}


-(void)asynRequestForImageArr:(NSMutableArray *)imageURLArr fromIndex:(NSInteger)index{

     NSInteger count=0;

    if (!_imageScrollView) {

        _imageScrollView=[[RequestImageScrollView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) imageURLArray:self.imageURLArray];

        _imageScrollView.removeDeleate=self;

    }else{

        [_imageScrollView setImageURLArray:imageURLArr];

    }

    if (!imageArray) {

        imageArray=[[NSMutableArray alloc]initWithArray:imageURLArr];

    }else{

        [imageArray removeAllObjects];

        [imageArray addObjectsFromArray:imageURLArr];

        [imageArray replaceObjectsInRange:NSMakeRange(0, index) withObjectsFromArray:imageDownloaded range:NSMakeRange(0, [imageDownloaded count])];

    }

    __block NSMutableArray *tmpImageArray=imageArray;

    __block NSInteger tmpCoun=count;

    __block NSMutableArray *tmpImageDownloaded=imageDownloaded;

    

    for (int i=index; i<[imageURLArr count]; i++) {

        NSString *imageURLString=[imageURLArr objectAtIndex:i];

        __block NSInteger tmpI=i;

        NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:imageURLString]];

        imageRequestOperation=[AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request,NSHTTPURLResponse *response,UIImage *image){

            [tmpImageArray replaceObjectAtIndex:tmpI withObject:image];

            tmpCoun++;

            if (tmpCoun==[imageURLArr count]-index) {

                 NSLog(@"success!");

                [_imageScrollView getDownloadedImageArray:tmpImageArray fromIndex:index];

                [tmpImageDownloaded removeAllObjects];

                [tmpImageDownloaded addObjectsFromArray:tmpImageArray];

                NSMutableDictionary *imageDownloadedDic=[[[NSMutableDictionary alloc]initWithObjectsAndKeys:imageURLArr,@"imageURLArr", nil]autorelease];

                [[NSNotificationCenter defaultCenter]postNotificationName:@"d.cnfinishimageDownloaded" object:nil userInfo:imageDownloadedDic];

            }

        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){

            

        }];

        [imageRequestOperation start];

    }

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值