美文网首页收藏ios
iOS网络图片瀑布流(未知图片高度)

iOS网络图片瀑布流(未知图片高度)

作者: 叩首问路梦码为生 | 来源:发表于2018-07-28 10:25 被阅读431次

    做过瀑布流的都清楚,,后台数据会返回图片的宽高,,经过比例处理会整齐的排列。。collectionview的加载图片的过程是先全部设置好没个item的高度,,添加占位图片,,sdwebimage下载图片,,下载完成显示在对应的imageView,,那么后台不返回尺寸该怎么办??有的demo是在数据处理的时候将图片下载下来,获取尺寸,添加进model里。。在collectionview刷新的时候再给item的尺寸,,这样做可以。。但会比较耗时。。有图片缓存还好,,如果是上拉加载新的图片。。用户体验会特别的差。你就等吧。

    与后台沟通后 结果是图片太多了 取尺寸太麻烦,,前台想办法。。。。。

    安卓和iOS 都采用了同一个思路 先给一个固定相同的高度,,线程获取图片尺寸,,获取结束后,再刷新高度,,虽然用户体验也极差,,会看到图片突然地变大或变小。。但没找到更好的办法。。下面是我的APP用到的关键代码

    
    #pragma mark  加载数据
    
    - (void)addData{
    
        __weakTuiJianViewController *weakSelf =self;
    
        dispatch_async(dispatch_get_global_queue(0,0), ^{
    
            [[CommuncationsharedInstance] loadShouYeTuiJianWithstart:requestStartlimit:limitsucess:^(id result) {
    
                /// 断网的情况请求出错时走缓存数据
    
                if ([resultisKindOfClass:[NSErrorclass]]) {
    
                    self.imagewarr = [NSMutableArrayarray];
    
                    self.imageharr = [NSMutableArrayarray];
    
                    requestResultArray = [NSMutableArrayarray];
    
                    requestResultArray = [NSKeyedUnarchiverunarchiveObjectWithFile:[PathToolthePath:@"TuiJianData"]];
    
                    for (NSDictionary *bodyin requestResultArray) {
    
                        NSString *imageUrl = imageUrl = body[@"video"][@"cover"];
    
                        /// 获取图片尺寸的方法,,有缓存从缓存中获取
    
                        CGSize size = [ImageSizeTool downloadImageSizeWithURL:[NSURLURLWithString:[NSStringstringWithFormat:@"%@%@",URLADDRESS,imageUrl]]];
    
                        [self.imagewarraddObject:[NSStringstringWithFormat:@"%f",size.width]];
    
                        [self.imageharraddObject:[NSStringstringWithFormat:@"%f",size.height]];
    
                    }
    
                    [weakSelf.tuijianCollectionViewreloadData];
    
                    [weakSelf.tuijianCollectionView.mj_footerendRefreshing];
    
                    [weakSelf.tuijianCollectionView.mj_headerendRefreshing];
    
                }else{
    
                    if (!result[@"state"]) {
    
                        if (result[@"customMessage"]) {
    
                            [[iToastmakeText:result[@"customMessage"]]show];
    
                        }
    
                    }else{
    
                        NSInteger num =requestStart;
    
                        requestStart =requestStart + [result[@"body"]count];
    
                        self.imagearr = [NSMutableArrayarray];
    
                        for (NSDictionary *bodyin result[@"body"]) {
    
                            if (![requestResultArraycontainsObject:body]) {
    
                                [requestResultArrayaddObject:body];
    
                            }
    
                            NSString *imageUrl = body[@"live"][@"cover"];
    
                            [self.imagearraddObject:imageUrl];
    
                            // 获取图片尺寸之前 先设置固定相同的尺寸 添加进宽高尺寸数组,,在你的瀑布流高度返回方法里进行按比例缩                         放,,设置瀑布流的高度
    
                            [self.imageharraddObject:@"500"];
    
                            [self.imagewarraddObject:@"900"];
    
                            [SVProgressHUD dismiss];
    
                        }
    
                        // 进行缓存 、、、、 这里的缓存是为断网情况有数据 ,,不是图片的缓存
    
                        [NSKeyedArchiverarchiveRootObject:requestResultArraytoFile:[PathToolthePath:@"TuiJianData"]];
    
                        dispatch_async(dispatch_get_main_queue(), ^{
    
                            [weakSelf.tuijianCollectionViewreloadData];
    
                            /// 回到主线程获取图片的尺寸
    
                            [selfjisun:self.imagearrnsinteger:num];
    
                            [weakSelf.tuijianCollectionView.mj_footerendRefreshing];
    
                            [weakSelf.tuijianCollectionView.mj_headerendRefreshing];
    
                        });
    
                        [SVProgressHUDdismiss];
    
                    }
    
                }
    
            }];
    
        });
    
    }
    
    
    - (void)jisun:(NSMutableArray *)arr nsinteger:(NSInteger)nsinteger{
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
    
            // 耗时的操作
    
            for (NSInteger i =0; i<arr.count; i++) {
    
                CGSize size = [ImageSizeTooldownloadImageSizeWithURL:[NSURLURLWithString:[NSStringstringWithFormat:@"%@%@",URLADDRESS,arr[i]]]];
    
                // 因为之前设置了相同的固定的尺寸  在这里获取到后进行替换
    
                [self.imagewarrreplaceObjectAtIndex:nsinteger + iwithObject:[NSStringstringWithFormat:@"%f",size.width]];
    
                [self.imageharrreplaceObjectAtIndex:nsinteger + iwithObject:[NSStringstringWithFormat:@"%f",size.height]];
    
            }
    
            dispatch_async(dispatch_get_main_queue(), ^{
    
                // 更新界面  尺寸获取后再刷新一遍
    
                    [self.tuijianCollectionViewreloadData];
    
            });
    
        });
    
    }
    
    
    
    获取尺寸方法 来自网络  先从缓存中找 没有再网络获取 可以节省时间
    +(CGSize)downloadImageSizeWithURL:(id)imageURL {
    
        NSURL* URL =nil;
    
        if([imageURLisKindOfClass:[NSURLclass]]){
    
            URL = imageURL;
    
        }
    
        if([imageURLisKindOfClass:[NSStringclass]]){
    
            URL = [NSURLURLWithString:imageURL];
    
        }
    
        if(URL ==nil)
    
            returnCGSizeZero;
    
        
    
        NSString* absoluteString = URL.absoluteString;
    
        
    
    #ifdef dispatch_main_sync_safe   从缓存中获取
    
        if([[SDImageCachesharedImageCache] diskImageExistsWithKey:absoluteString]){
    
            UIImage* image = [[SDImageCachesharedImageCache] imageFromMemoryCacheForKey:absoluteString];
    
            if(!image){
    
              NSData* data = [[SDImageCachesharedImageCache] performSelector:@selector(diskImageDataBySearchingAllPathsForKey:)withObject:URL.absoluteString];
    
                image = [UIImageimageWithData:data];
    
            }
    
            if(image){
    
                return image.size;
    
            }
    
        }
    
    #endif  从网络获取
    
        NSMutableURLRequest *request = [[NSMutableURLRequestalloc] initWithURL:URL];
    
        NSString* pathExtendsion = [URL.pathExtensionlowercaseString];
    
        
    
        CGSize size =CGSizeZero;
    
        if([pathExtendsionisEqualToString:@"png"]){
    
            size =  [selfdownloadPNGImageSizeWithRequest:request];
    
        }elseif([pathExtendsionisEqual:@"gif"]){
    
            size =  [selfdownloadGIFImageSizeWithRequest:request];
    
        }else{
    
            size = [selfdownloadJPGImageSizeWithRequest:request];
    
        }
    
        if(CGSizeEqualToSize(CGSizeZero, size)){
    
            NSData* data = [NSURLConnectionsendSynchronousRequest:[NSURLRequestrequestWithURL:URL] returningResponse:nilerror:nil];
    
            UIImage* image = [UIImageimageWithData:data];
    
        if(image){
    
    #ifdef dispatch_main_sync_safe
    
            [[SDImageCachesharedImageCache] storeImage:image recalculateFromImage:YESimageData:data forKey:URL.absoluteStringtoDisk:YES];
    
    #endif
    
                size = image.size;
    
            }
    
        }
    
        return size;
    
    }
    
    +(CGSize)downloadPNGImageSizeWithRequest:(NSMutableURLRequest*)request{
    
        [request setValue:@"bytes=16-23"forHTTPHeaderField:@"Range"];
    
        NSData* data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
    
        if(data.length ==8){
    
            int w1 =0, w2 = 0, w3 =0, w4 = 0;
    
            [data getBytes:&w1range:NSMakeRange(0,1)];
    
            [data getBytes:&w2range:NSMakeRange(1,1)];
    
            [data getBytes:&w3range:NSMakeRange(2,1)];
    
            [data getBytes:&w4range:NSMakeRange(3,1)];
    
            int w = (w1 <<24) + (w2 << 16) + (w3 <<8) + w4;
    
            int h1 =0, h2 = 0, h3 =0, h4 = 0;
    
            [data getBytes:&h1range:NSMakeRange(4,1)];
    
            [data getBytes:&h2range:NSMakeRange(5,1)];
    
            [data getBytes:&h3range:NSMakeRange(6,1)];
    
            [data getBytes:&h4range:NSMakeRange(7,1)];
    
            int h = (h1 <<24) + (h2 << 16) + (h3 <<8) + h4;
    
            returnCGSizeMake(w, h);
    
        }
    
        returnCGSizeZero;
    
    }
    
    +(CGSize)downloadGIFImageSizeWithRequest:(NSMutableURLRequest*)request{
    
        [request setValue:@"bytes=6-9"forHTTPHeaderField:@"Range"];
    
        NSData* data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
    
        if(data.length ==4){
    
            short w1 =0, w2 = 0;
    
            [data getBytes:&w1range:NSMakeRange(0,1)];
    
            [data getBytes:&w2range:NSMakeRange(1,1)];
    
            short w = w1 + (w2 <<8);
    
            short h1 =0, h2 = 0;
    
            [data getBytes:&h1range:NSMakeRange(2,1)];
    
            [data getBytes:&h2range:NSMakeRange(3,1)];
    
            short h = h1 + (h2 <<8);
    
            returnCGSizeMake(w, h);
    
        }
    
        returnCGSizeZero;
    
    }
    
    +(id)diskImageDataBySearchingAllPathsForKey:(id)key{returnnil;}
    
    +(CGSize)downloadJPGImageSizeWithRequest:(NSMutableURLRequest*)request{
    
        [request setValue:@"bytes=0-209"forHTTPHeaderField:@"Range"];
    
        NSData* data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
    
        if ([datalength] <= 0x58) {
    
            returnCGSizeZero;
    
        }
    
        if ([datalength] < 210) {//肯定只有一个DQT字段
    
            short w1 =0, w2 = 0;
    
            [data getBytes:&w1range:NSMakeRange(0x60,0x1)];
    
            [data getBytes:&w2range:NSMakeRange(0x61,0x1)];
    
            short w = (w1 <<8) + w2;
    
            short h1 =0, h2 = 0;
    
            [data getBytes:&h1range:NSMakeRange(0x5e,0x1)];
    
            [data getBytes:&h2range:NSMakeRange(0x5f,0x1)];
    
            short h = (h1 <<8) + h2;
    
            returnCGSizeMake(w, h);
    
        } else {
    
            short word =0x0;
    
            [data getBytes:&wordrange:NSMakeRange(0x15,0x1)];
    
            if (word ==0xdb) {
    
                [data getBytes:&wordrange:NSMakeRange(0x5a,0x1)];
    
                if (word ==0xdb) {//两个DQT字段
    
                    short w1 =0, w2 = 0;
    
                    [data getBytes:&w1range:NSMakeRange(0xa5,0x1)];
    
                    [data getBytes:&w2range:NSMakeRange(0xa6,0x1)];
    
                    short w = (w1 <<8) + w2;
    
                    short h1 =0, h2 = 0;
    
                    [data getBytes:&h1range:NSMakeRange(0xa3,0x1)];
    
                    [data getBytes:&h2range:NSMakeRange(0xa4,0x1)];
    
                    short h = (h1 <<8) + h2;
    
                    returnCGSizeMake(w, h);
    
                } else {//一个DQT字段
    
                    short w1 =0, w2 = 0;
    
                    [data getBytes:&w1range:NSMakeRange(0x60,0x1)];
    
                    [data getBytes:&w2range:NSMakeRange(0x61,0x1)];
    
                    short w = (w1 <<8) + w2;
    
                    short h1 =0, h2 = 0;
    
                    [data getBytes:&h1range:NSMakeRange(0x5e,0x1)];
    
                    [data getBytes:&h2range:NSMakeRange(0x5f,0x1)];
    
                    short h = (h1 <<8) + h2;
    
                    returnCGSizeMake(w, h);
    
                }
    
            } else {
    
                returnCGSizeZero;
    
            }
    
        }
    
    }
    
    
    
    

    下面是一个大神用SDWebImage 实现的瀑布流 github地址:https://github.com/songhailiang/DynamicWaterfall

    相关文章

      网友评论

        本文标题:iOS网络图片瀑布流(未知图片高度)

        本文链接:https://www.haomeiwen.com/subject/qdtomftx.html