1. 背景
设计给出图形设计之后,客户端要视觉还原,将图片存在本地,并设置到UIImageView上。 需要注意对不同机型进行适配。
2. 遇到的问题
设计师一般是基于iPhoneX的尺寸,375*850。单位是pt。正常情况下,客户端代码只需要用设计稿给的尺寸设置就可以了,UIImageView的宽高比和设计稿给的图片尺寸一致。问题在于,可能有需求,要求UIImageView的宽度不变的情况下,高度减小。
这种情况下,图片不仅比UIImageView要大,而且宽高比不一样。应该如何设置呢?
3. 解决方案
首先,UIImageView有多种contentMode,
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
前五个是常用的。 第一个UIViewContentModeScaleToFill是默认情况下的contentMode,会将图片进行拉伸,直到填充满整个UIImageView
这里有个问题,如果图片比UIImageView小,那么这个拉伸,直到填充满,很好理解。
那如果图片本来就已经比UIImageView 大了呢?图片会先自动做一波缩放,直到图片的最短边和UIImageView的最短边一样大,然后再对图形的长边进行拉伸。
如果此时我们不做任何的其他处理,拉伸会导致图片变形,不是我们要的效果。
怎么办呢,我们可以设置图片不能拉伸的区域,通过- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode方法,其中capInsets,通过设定距离图片上、左、下、右的距离,设置了一个矩形区域。在这个矩形区域内,是不会被拉伸的。
综上,我们可以不设置UIImageView的contentMode(因为默认就是UIViewContentModeScaleToFill)。然后设置一下防止拉伸的区域。在图片由于UIViewContentModeScaleToFill需要进行拉伸的时候,我们设置的防拉伸就能生效,保证图片不变形。
ContentMode 和 resizableImageWithCapInsets 可以拆开单独用,也可组合在一起用,具体取决于你的需求