How can you be a good designer if you do UI development every day without recording something?
As an iOS developer, we are all familiar with image stretching on iOS. Especially with storyboards, it’s so friendly, you can control the stretching of images without writing a line of code, it’s so friendly. If you are not familiar with image stretching, you can read the article “Several ways to stretch images in iOS” in Jane’s book, which is more detailed. I won’t go into the details of stretching here. However, what I want to share today is a picture stretching deformation problem, which is also a small problem I encountered in the actual development.
The problem
Here’s the original, and I want to stretch the middle left and right without leaving the left intact.
- The original image is 53 high and 127 wide
Here’s what I was hoping for:
- In the image above, the imageView is 53 in height and the width of the screen. (Get as expected)
On top I just stretch the middle left and right to get the desired effect. The specific code is as follows:
Imageview1.image = image? Imageview1.image = image? .resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: 53, bottom: 0, right: 53), resizingMode: .stretch)Copy the code
But whenimageView
Height > 53, still stretching the middle part, but not the desired effect. The comparison screenshots of the two cases are as followsimageView1
与 imageView3
Of the same width,imageView1
Height is 53,imageView3
The height is 80.
So why does this happen?
Analysis of the
I made a few sketches before going into the analysis. So that makes the problem a little bit more intuitive.
As shown in the figure above, since it is the middle of the left and right stretch, that is, the red square in the figure above, as shown by the arrow, and stretch to the left and right, the width of the yellow block on the left and the blue block on the right remain the same throughout the stretch. The result of stretching is shown below:However, if the height of the view is greater than the height of the image, the yellow and blue blocks will be larger than the width, regardless of whether the image is stretched or not. The results are shown below:Hence the above phenomenon. To summarize, stretch an image if you want to keep the width to height ratio of a part of the image constant. (The only thing to blame here is unique requirements.)
So what can be done about it?
To solve
In the example above, if you want to keep the width to height ratio of the yellow block on the left, and the width to height ratio of the blue block on the right, you can’t just stretch. The author can offer two ideas here:
-
Keep the width to height control of the stretched image in line with the width to height control of the view. And then we do that by scaling. Obviously it won’t work if you use the resizableImage method provided by the system. Because it only has two parameters, one is the area you need to protect and the other is how to spread it out. Unable to stretch to the specified size. I have also looked at other interfaces provided by the system here, and it seems that none of them can be stretched to the specified size. So this way decisively give up.
-
First resize the image to the width and height ratio, and then stretch it. Combining the above example, we want to stretch left and right, so we need to resize the height of the image to the same height of the view, and then stretch. The actual effect is shown below:
Perfect solution, the specific code is as follows:
let imageSize = image! .size let ratio = imageView3.frame.height / imageSize.height imageView3.image = image?.resize(to: CGSize(width: ratio * imageSize.width, height: imageView3.frame.height)).resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: imageView3.frame.height, bottom: 0, right: 53), resizingMode: .stretch)Copy the code
Resize:
extension UIImage { func resize(to size: CGSize) -> UIImage { if size.height == 0 || size.width == 0 { return self } UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) guard let image = UIGraphicsGetImageFromCurrentImageContext() else { UIGraphicsEndImageContext() return self } UIGraphicsEndImageContext() return image } }Copy the code
Note that when you resize the image, you must pay attention to the change of the protected area when you stretch it. In the example above, the width of the left side of the protected area is updated after resize as long as the desired aspect ratio of the protected area is met.
conclusion
There’s nothing wrong with image stretching. For most needs, just stretching the middle area is a perfect solution, but if you do have a problem like mine, you need to analyze the situation and adjust the image accordingly.
Reference:
Several ways to stretch images in iOS
The ~