美文网首页iOS DeveloperiOS 开发
UIView上加载多个尺寸不同的网络图片时的布局问题

UIView上加载多个尺寸不同的网络图片时的布局问题

作者: 旅橙 | 来源:发表于2016-04-19 15:50 被阅读906次
    • 点击Cell跳转进另一个页面时,是一个展示多图的页面(该页面暂时需要布局的只有标题和图片).项目中页面需要用到一个展示多个网络图片的页面,但图片高低不尽相同.而且图片异步加载完成的时间不同,不能将高度固定.
      实际开发中遇到的排版问题,经过讨论和测试采用了本文的方法.思路是先使用给定高度的缺省图占位(先根据占位图高度设定UIView高度),图片缓存完毕后再重新计算调整.
    1.创建用于存放imgView的view
      //此处命名有缺陷
      _headerImgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [DMDevceManager screenWidth], 0)];
      _headerImgView.backgroundColor = [UIColor whiteColor];
      _headerImgView.userInteractionEnabled = YES;
    
    2.创建一个数组用来存放图片高度(按位存放,最多十张)
      //此处使用这种方法来创建数组是因为图片异步加载时时间先后不确定,所以要按图片位置来将数据插入数组
      tmpHeightArr = [NSMutableArray arrayWithArray:@[@0,@0,@0,@0,@0,@0,@0,@0,@0,@0]];
    
    3.每张图片先给定400高度,加上占位图告诉用户图片正在加载.
      //_imgViewHeight是整个大的用于存放所有图片的View的高度
      _imgViewHeight = 40 + (300+5) * _model.imagesArray.count; 
    
    4.使用循环创建图片的imgView.
      //使用tag值标记每个view,方便取出改变高度
      for (int i = 0  ;i < _model.imagesArray.count ; i++)
          {
        UIImageView * imgView = [[UIImageView alloc]init];
        imgView.contentMode = UIViewContentModeScaleAspectFill;
       //[DMDevceManager screenWidth] 是屏幕宽度
        imgView.frame = CGRectMake(10, 45 + 300*i, [DMDevceManager screenWidth] - 20, 300);
        imgView.tag = i + 10000;
        imgView.image = [UIImage imageNamed:@"pic_11"];
        [_headerImgView addSubview:imgView];
          }
    
    5.使用SDImage来缓存图片真实高度存进数组
       for (int i = 0  ;i < _model.imagesArray.count ; i++)
        {
        UIImageView * imgView = (UIImageView *)[_headerImgView viewWithTag:10000 + i];
        [imgView sd_setImageWithURL:_model.imagesArray[i]
                   placeholderImage:[UIImage imageNamed:@"pic_11"]
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
         {
             //如果已经缓存到图片才调用此方法
             if (image.size.width > 0)
             {
                  //根据图片实际纵横比计算出图片高度,防止图片显示时被拉伸
                 CGFloat height = ([DMDevceManager screenWidth] - 20)/(image.size.width/image.size.height);
                 //按位置替换掉存放图片高度的数组的初始值
                 [tmpHeightArr replaceObjectAtIndex:i withObject:@(height)];
                //下文方法
                 [self createImgs];
             }
         }];
        }
    
    6.将改变高度的方法另行封装,上文中调用
      #pragma mark - createImg
      - (void)createImgs
      {
          for (int i = 0; i < _model.imagesArray.count ; i ++)
          {
        //根据tag取出图片的imageView
        UIImageView * imgView = (UIImageView *)[_headerImgView viewWithTag:10000 + i];
        if([tmpHeightArr[i] integerValue]>0)
           {
            //高度赋值
            imgView.height = [tmpHeightArr[i] floatValue];
           }
        //根据图片的高度调整各图片的位置(纵坐标y)
        for (int j = i+1;j < _model.imagesArray.count + 1; j++ )
           {
            UIImageView * tmpImgView = (UIImageView *)[_headerImgView viewWithTag:10000 + j];
            tmpImgView.y = imgView.bottomY + 5;
           }
        if (i == _model.imagesArray.count - 1)
        {
              //整个view的高度等于最后一张图片的下边界Y值
            _imgViewHeight = imgView.bottomY;
        }
       }
          [_tableView reloadData];
      }
    
    • 没有使用Coretext图文混排;
    • 实现的效果是进入页面,model传进一个images URL的数组,先使用按数组count给页面固定高度.(每个占位图也可以使用转圈的加载动画).
    • 图片异步加载过程中,哪个图片先加载完毕就修正imgView的高度和位置.尚未加载完毕就显示占位图但不错位.
    • 最终加载完毕图片宽度一致,上下间距一致且不被拉伸变形.

    相关文章

      网友评论

        本文标题:UIView上加载多个尺寸不同的网络图片时的布局问题

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