引言

需求:要求图片展示不变形,比如商品详情页。 核心原理:按照图片的原宽高比例进行显示图片全部内容,并自动适应高度

I 原理

  • 按照图片的原来宽高比进行缩
  • UICollectionView的高度自适应

1.1 按照图片的原来宽高比进行缩

首先了解下图片的内容模式

  • UIViewContentModeScaleToFill


拉伸图片至填充整个UIImageView,图片的显示尺寸会和imageVew的尺寸一样 。


This will scale the image inside the image view to fill the entire boundaries of the image view.

  • UIViewContentModeScaleAspectFit


图片的显示尺寸不能超过imageView尺寸大小


This will make sure the image inside the image view will have the right aspect ratio and fits inside the image view’s boundaries.

  • UIViewContentModeScaleAspectFill


按照图片的原来宽高比进行缩放(展示图片最中间的内容),配合使用​​ tmpView.layer.masksToBounds = YES;​

This will makes sure the image inside the image view will have the right aspect ratio and fills the entire boundaries of the image view. For this value to work properly, make sure that you have set the clipsToBounds property of the image view to YES.


  • UIViewContentModeScaleToFill : 直接拉伸图片至填充整个imageView

划重点

UIViewContentModeScaleAspectFit : 按照图片的原来宽高比进行缩放(一定要看到整张图片)


使用场景:信用卡图片的展示


iOS小技能:UICollectionView的自适应案例详解:(商品详情页)_宽高

UIViewContentModeScaleAspectFill : 按照图片的原来宽高比进行缩放(只能图片最中间的内容)

  • 引导页通常采用UIViewContentModeScaleAspectFill
// 内容模式
self.contentMode = UIViewContentModeScaleAspectFill;
// 超出边框的内容都剪掉
self.clipsToBounds = YES;

1.2 UICollectionView的高度自适应的原理

  • CollectionView根据 layout 的 estimatedItemSize 算出估计的 contentSize
//1、设置 UICollectionViewFlowLayout 的 estimatdItemSize 的预估高度
layout.estimatedItemSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 200);//estimatdItemSize 的默认值为 CGSizeZero ,所以要给一个非0值开启高度估算。
  • CollectionView 在显示的过程中,即将被显示的 cell 根据 autolayout 的约束算出自适应内容的 size
/**
CollectionView 在显示的过程中,即将被显示的 cell 根据 autolayout 的约束算出自适应内容的 size

*/
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[self setNeedsLayout];
[self layoutIfNeeded];
CGSize size = [self.contentView systemLayoutSizeFittingSize:layoutAttributes.size];
CGRect cellFrame = layoutAttributes.frame;
cellFrame.size.height = size.height;
layoutAttributes.frame = cellFrame;
return layoutAttributes;
}
  • iOS8适配
//解决iOS 8 上不能自动布局的问题
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
return YES;// return YES to cause the collection view to requery the layout for geometry information
}

实现

2.1 核心实现步骤


1、根据需求要求先选择 ​​UIViewContentModeScaleAspectFit​​​或者​​UIViewContentModeScaleAspectFill​​ 2、接下来再视图的大小比例尽量接近图片比例


第一步先设置内容模式为​​UIViewContentModeScaleAspectFit​​,先等比例显示图片内容,如下图,此时按照图片的原来宽高比进行缩放显示


明显地可以看出,图片视图的宽是固定的,第二部我们只要简单地处理自适应高度即可


iOS小技能:UICollectionView的自适应案例详解:(商品详情页)_ios_02

第二步:自适应高度


UICollectionView的高度自适应


[self.testImage mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.width.top.mas_equalTo(self.contentView);

make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width*self.testImage.image.size.height/self.testImage.image.size.width);




}];

iOS小技能:UICollectionView的自适应案例详解:(商品详情页)_ios_03

2.1 完整demo源码

demo地址获取请关注小程序:iOS逆向,搜索【商品详情页】


  1. 应用场景:商品详情页以及需要展示大量图片的界面
  2. 核心原理

2.1)​​按照图片的原来宽高比进行缩​

2.2)​​UICollectionView的高度自适应​

案例采用Masonry布局


III 、see also

更多内容请关注 #小程序:iOS逆向,只为你呈现有价值的信息,专注于移动端技术研究领域;更多服务和咨询请关注#公众号:iOS逆向。