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

做过瀑布流的都清楚,,后台数据会返回图片的宽高,,经过比例处理会整齐的排列。。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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容