I created a UIImageView in IB with a Content Mode of Aspect Fit. I'm then loading a large image to that view from a URL.
#IBOutlet weak var pictureView: UIImageView!
NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, _, error) -> Void in
guard let data = data where error == nil,
let image = UIImage(data: data)
else {
print(error?.localizedDescription)
return
}
pictureView.image = image
pictureView.clipsToBounds = true
setNeedsLayout()
layoutIfNeeded()
}).resume()
The image loads in the the UIImageView, and Aspect Fit resizes the image correctly to display it all in the frame, however the frame of the UIImageView is set to the size of the original large image. I have this huge frame wrapping this smaller resized image. I need the UIImageView frame to tightly wrap the Aspect Fit UIImage, throwing off all my other formatting.
Do I need to somehow calculate a new frame size manually for the UIImageView, or am I missing a setting somewhere?
EDIT:
I've also tried the following to resize the UIImageView frame around the image:
pictureView.frame = AVMakeRectWithAspectRatioInsideRect(picture.size, pictureView.frame)
and...
pictureView.frame = CGRectMake(self.pictureView.frame.origin.x, self.pictureView.frame.origin.y, pictureImage.size.width, pictureImage.size.height)
And I've also tried playing with the compression resistance settings.
Well there a few things that are involved.
The dependencies :
1) The image size. If the image height/width ratio is not greater than or equal to ImageView height/width ratio, then there will be black space shown, as there will be less ratio to match to the ImageView.
2) I am unsure of the constrains of your imageView, since I can see it is an #IBOutlet.
I am confused on your sentence "however the frame of the UIImageView is set to the size of the original large image. I have this huge frame wrapping this smaller resized image."
I believe what you are wanting to do is set the image into the imageView, but it seems that you are setting the UIImageView into the image size then the image into UIImageView, which makes it really confusing to debug. Could you explain more detailed exactly what you are wanting to happen?
EDIT
There is an ImageView with a frame -- this frame will NEVER be different.
The contentMode will change how the image is displayed on the imageView
The UIViewContentModeScaleAspectFit and UIViewContentModeScaleAspectFill modes scale the image to fit or fill the space while maintaining the image’s original aspect ratio.
The UIViewContentModeScaleToFill value scales the image without regard to the original aspect ratio, which can cause the image to appear distorted.
UIViewContentModeScaleToFill
The option to scale the content to fit the size of itself by changing the aspect ratio of the content if necessary.
*(Wouldn't recommend for most cases)
UIViewContentModeScaleAspectFit
The option to scale the content to fit the size of the view by maintaining the aspect ratio. Any remaining area of the view’s bounds is transparent.
*(This one guarantees that the WHOLE IMAGE fits on the screen. So if the image is smaller ratio than the screen, then there will be black on some edges, either top/bottom or left/right)
UIViewContentModeScaleAspectFill
The option to scale the content to fill the size of the view. Some portion of the content may be clipped to fill the view’s bounds.
*(This one guarantees that the WHOLE IMAGEVIEW is taken)
Related
I'm using UIImageView with Content Mode set to Aspect Fit. UIImageView resizes correctly my image but it doesn't change own frame after resizing even there is no constraints set.
What I need:
I need UIImageView to resize own frame according image inside. I've configured image view at Storyboard.
I need to layout again other objects at view because UIImageView's size is changed.
What I've tried:
I've created:
UIViewController (white background) → UIImageView (gray background) → sample image inside it.
Constraints: leading & trailing constraints set to zero, Y constraint is set to align UIImageView vertically.
As you see after image scaled correctly UIImageView's frame is still has incorrect size (gray background).
I've tried to set UIImageView size manually:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let newSize = AVMakeRect(aspectRatio: backgroundImageView.image!.size, insideRect: backgroundImageView.frame)
backgroundImageView.frame = newSize
}
In that example code I've calculated image size and set frame size to image's size. I don't know if it is better way so I don't need to use AVFoundation's methods.
Problem: other object is place incorrectly because UIImageView's size changed and constraints are invalid now.
That methods doesn't work for me:
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
Even I will call my UIImageView size calculation at viewDidLayoutSubviews() other constraints is still using old UIImageView's size.
Questions
How to change UIImageView's size correctly? Maybe I can do it without code? Maybe I need to play with Hugging/Compression? I've tried something but got no luck.
How to force view to recalculate other constraints so they will use new UIImageView size? For example I can put red square at the top of UIImageView, but after UIImageView has been resized by my method, red square still will be at the old UIImageView's position.
I'm trying to set the background image of a UIView with animated .gif's that I'm pulling form Giphy.
The problem I'm having is that the UIView is stretching the image. I want to fill the background so the height is 100% and have it centered. So left and right of the .gif would be cut off - but the image would be centered on the screen and not stretched.
Here's a screenshot of what it looks like now.
You can see it's fills height correct but it's shrinking the width of the image to match the UIView dimensions making it look stretched.
Here is the code I have now:
override func viewDidAppear(animated: Bool) {
self.giphyBackground(Title: "dancing") { [weak self] (gifUrl) -> Void in
let gifView = FLAnimatedImageView(frame: self!.giphy.frame)
gifView.animatedImage = FLAnimatedImage(animatedGIFData: NSData(contentsOfURL: NSURL(string: gifUrl)!)!)
self?.view.insertSubview(gifView, aboveSubview: self!.giphy)
}
}
Any ideas
I think you should set the content mode of gifView to Aspect Fit, doing so will not stretch the image and will fully fill at-least one of the length either horizontally/ vertically.
Try setting
gifView.contentMode = UIViewContentMode.ScaleAspectFit
Also you can use scale AspectFill on gifView as
gifView.contentMode = UIViewContentMode.ScaleAspectFill
ScaleAspectFill will fill the entire gifView's frame but will also maintain the aspect ratio, doing so your image won't look stretched but it could happen that content either horizontally or vertically will go outside the frame(which you can clip).
You are definitely looking for the view's contentMode ScaleAspectFit. Simply add a line gifView.contentMode=UIViewContentMode.ScaleAspectFit
In the app that I am making I have some background images for some labels.
The image is 500x550 pixels but my label is 250x275 pixels.
How can I make the code change the width and height of the background so it fits the size of the label?
Code I have now:
lblMainNumber.backgroundColor = UIColor(patternImage: UIImage(named: "image.png")!)
It is easier to have a container UIView with size of 250 x 275 that will contain 2 subviews with same size:
1) a UIImageView with your image (set its contentMode to UIViewContentModeScaleAspectFit)
2) UILabel with your text. It will be on top of the UIImageView to stay visible.
You would possibly want to set both subviews (via autolayout) to match the size of container view.
Pattern image approach is pain in the ass and not wort the effort.
I am trying to add some images to my UIImageView. Everything works fine if the png has the same size as the ImageView.
But when I insert a bigger image, it is not discarded.
This is my code:
#IBOutlet weak var PictureView: UIImageView!
func loadSomePicture() {
var examplePicture = UIImage(named: "Block.png")
PictureView.image = exampleProfilePicture
PictureView.layer.cornerRadius = 50
PictureView.clipsToBounds = true
Althoug the clipsToBounds property is set true and the View Mode is Scale to fill, the image stays in its original size.
Thanks for Your help!
check Clip Subviews in Drawing options
I believe the problem is occurring because you are setting the contentMode to "Aspect Fill", instead of "Scale To Fill". Can you maybe explain a little more what you want the ImageView and Image to end up as? "Aspect Fill" will always try and keep the image's aspect ratio while filling it to the ImageView's size dimensions.
First of all I'm trying to lazy load images from remote url and what I've done so far is as follows,
- I have created custom UITableViewCell which contains on UIImageView and other labels using XIB and mapped it to my custom UITableViewCell class.
- I'm using the custom table cell in my UITableView
- UIImageView inside the custom cell, loads remote image as per Apple's tutorial for lazy loading images for tableview
- Initially ImageView displays an loading image, once the image is loaded, the loaded image gets updated inside ImageView or if it fails, No Image will get displayed
And the problem here is, the remote images are of variable sizes, lets say if the image is smaller than the ImageView frame the image stretches and display as blurry but once we scroll or on row selection its re-size to actual size and looks fine.
At the same time if the image is larger than the ImageView frame it fits correctly fit inside the frame but again if we scroll or select the row it occupy size bigger than frame and hides other elements in the row
And I searched for hours and all I got is setting content mode to UIViewContentModeScaleToFit and setting clipsToBounds to 'YES', I made those changes as well both in XIB, as well as in Code but it doesn't change anything. Can someone point me, on what I'm doing wrong or how to fix this issue.
Thanks.
Grab the image however you want
UIImage *customImage = [UIImage imageWithContentsOfFile:theImagePath];
Then check the size of the image using:
NSLog(#"the customImage width is %f and height is %f ",customImage.size.width,customImage.size.height);
Then modify the width and height of the frame that your placing it in so that they are set to an equal fraction of whatever the original image was (while still fitting in the necessary bounds)
float newWidth = customImage.size.width *.4;
float newHeight = customImage.size.height *.4;
ImageButton.frame = CGRectMake(x coord, y coord, newWidth, newHeight);
You can also throw on aspect fit/fill if necessary
I just re-sized the image, if the image's width and height is greater than the frame size and displayed the re-sized image on it, and if the image dimension is smaller than the frame I displayed as it is.