I have UIView ancestor - let say MyView, which overrides method -drawInRect to display an image
override func draw(_ rect: CGRect) {
super.draw(rect)
image?.draw(in: rect)
/*some code here*/
}
This view is scaling in both directions at some point. After enlarging, displayed image loses it's quality. Saying, if I create MyView with size 20*20, bounds property remains the same after scaling, but transformed image I'm trying to display is low quality, because I'm trying to paint it with the same 20x20 size. Is there any way to draw an image respectively to my view scaling?
First, strongly consider using a UIImageView
as a subview rather than trying to implement even modestly complicated image drawing yourself. UIImageView
is optimized for many of the problems you can face. It's not perfect, and sometimes it's possible to do better by hand if you know what you're doing, but it does its job well.
To your specific problem, your contentMode
is almost certainly scaleToFill
(that's the default). The simplest solution is to change it to redraw
to force a full redraw when the bounds change. That's not highly efficient, but may be ok for your problem (it often is fine). Making it both high quality and highly efficient is a bit more complicated, and often requires a lot of special knowledge how your app behaves. For the easy cases, making this high quality and efficient is what UIImageView
does for you.
If you're reliably scaling from 20x20 to some other specific size, and you don't have too many views, another trick is to draw at your full size and then scale down to 20x20. This is very inefficient if you have a lot of views and the size of the final images is large, but can be very fast and high quality, so is something to at least consider. I've done this to deal with small zooms (for example to 110% size). It probably wouldn't be a good way to turn thumbnails into full-screen images, though.