Insets to UIImageView?
IosIphoneUiimageviewStoryboardIos Problem Overview
I would like to achieve :
- Scale to fill mode of image view
- Insets to
UIImageView
so that image does not meet the edges of theUIImageView
Bottomline: I want to increase the touch area of the UIImageView
without stretching the image beyond certain size.
Is it possible through storyboard ? If not can anyone tell how to do it programmatically ?
I can achieve similar functionality through a UIButton
and setting image inset through storyboard but I can't find any such thing with UIImageView
.
Ios Solutions
Solution 1 - Ios
You can add inset to UIImage
instead of UIImageView
.
Swift 4
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.image = UIImage(named: "example")?.withAlignmentRectInsets(UIEdgeInsets(top: -4, left: 0, bottom: -4, right: 0))
Solution 2 - Ios
Using the method given here :
UIImage *image= [MyUtil imageWithImage:[UIImage imageNamed:@"MyImage"] scaledToSize:CGSizeMake(80, 80)];
UIImageView* imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imgView.contentMode = UIViewContentModeCenter;
[imgView setImage:image];
Now your insets become 100-80 i.e. 20 .
This is a workaround to provide insets to an UIImageView. Better answers are welcomed.
Solution 3 - Ios
It looks like you want to have a touchable imageView, so why not using an UIButton with image and imageEdgeInsets?
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setFrame:someFrame];
[b setImage:img forState:UIControlStateNormal];
b.imageEdgeInsets = UIEdgeInsetsMake(20, 20, 20, 20);
[b addTarget:self action:@selector(imageClicked:) forControlEvents:UIControlEventTouchUpInside];
Solution 4 - Ios
My Code
- minus inset: smaller image
- plus inset: larger image
Swift4
private lazy var imageView: UIImageView = {
let view = UIImageView()
view.contentMode = .scaleAspectFit
let insetValue: CGFloat = -8
view.image = image.withAlignmentRectInsets(UIEdgeInsets(top: insetValue, left: insetValue, bottom: insetValue, right: insetValue))
return view
}()
Solution 5 - Ios
Do not suffer, try this:
After trying for a while I found this solution:
extension UIImage {
func withInset(_ insets: UIEdgeInsets) -> UIImage? {
let cgSize = CGSize(width: self.size.width + insets.left * self.scale + insets.right * self.scale,
height: self.size.height + insets.top * self.scale + insets.bottom * self.scale)
UIGraphicsBeginImageContextWithOptions(cgSize, false, self.scale)
defer { UIGraphicsEndImageContext() }
let origin = CGPoint(x: insets.left * self.scale, y: insets.top * self.scale)
self.draw(at: origin)
return UIGraphicsGetImageFromCurrentImageContext()?.withRenderingMode(self.renderingMode)
}
}
Usage example:
let margin:CGFloat = 16
self.imageView.image = image?.withInset(UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin))
Solution 6 - Ios
One option is to use withAlignmentRectInsets
, but it doesn't work with the layer border.
Another way is to use resizableImage(withCapInsets: resizingMode: .stretch)
where you'd want to use positive inset values for smaller images.
Sample code:
private func setupQRImageView() -> UIImageView {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.layer.borderColor = Default.imageBorderColor.cgColor
imageView.layer.borderWidth = 4.0
imageView.layer.cornerRadius = 6.0
let imageInset: CGFloat = 8.0
imageView.image = UIImage(named: "QR")?.resizableImage(withCapInsets: UIEdgeInsets(top: imageInset, left: imageInset, bottom: imageInset, right: imageInset), resizingMode: .stretch)
return imageView
}
Produces the following result:
Solution 7 - Ios
You can add a UIView
first and then you add your UIImageView
inside the UIView
with a padding of whatever you like, and if you want your gesture to get affected only in UIImageView
, make it UserInteractionEnable to yes or if you want the gesture to be in the whole then you can add the gesture to the whole UIView