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
Related
I am trying to set the contentMode of a UIImageView to be .top, that is contained within a UIView, but it's not set properly or runs out of the boundary of the UIView.
This is what my cell looks like with the red being the container UIView with constraints of the UIImageView:
FYI: The UIImageView is a square size because it will be applied with rounded corners.
What I've attempted to do and the result:
1.
thumbnail.contentMode = .top
thumbnail.clipsToBounds = true
thumbnail.sizeToFit()
2.
thumbnail.contentMode = .top
thumbnail.clipsToBounds = true
also tried adding:
thumbnailContainer.clipsToBounds = true
thumbnailContainer.sizeToFit()
What I'm trying to achieve is the result of the first screenshot with the UIImageView contained inside its container view as seen in the second screenshot.
UPDATE:
Based on the comments and answer, I believe some are confused on what exactly I'm trying to do, so I've attached another screenshot of the result I'm expecting :
As you can see, I want the contentMode of the UIImageView to be .top such that the top-middle of the image is displayed. You can clearly see the difference between the contentMode in the 3rd screenshot, which is .scaleAspectFit, versus the contentMode in the 4th screenshot, which is .top because it is showing the top-middle of the image.
However, I would like the UIImageView to maintain its original size, as seen in the 3rd screenshot where the contentMode is .scaleAspectFit, instead of being stretched out horizontally and vertically, as seen in the 2nd screenshot.
I hope this clarifies what I'm trying to achieve.
To achieve the result you want, you need to set content mode to .aspectFit, so that image will resize itself in UIImageView's size, keeping its original height to width ratio.
I wanted to circle my UIImageView and added this code :
profileImage.layer.cornerRadius = profileImage.frame.size.height/2
profileImage.clipsToBounds = true
and it work perfectly, but when images are horizontal, I get this picture:
as you can see, there is white space at the bottom and top of my circle image view. but what I really wanted was a circle filled with my image!
I've tried changing "content Mode" from attribute inspector, but I didn't get any answer! how can I fix this issue?
You have already set the clipsToBound property. So just update the contentMode.
I you don't want to distort image's scale:
profileImage.contentMode = .scaleAspectFill
If image's scale does not matter, you also can use:
profileImage.contentMode = .scaleToFill
Follow the link for more details: https://useyourloaf.com/blog/stretching-redrawing-and-positioning-with-contentmode/
Use below code:-
profileImage.clipsToBounds = true
profileImage.contentMode = .scaleAspectFill
Set the contentMode of your UIImageView to scaleAspectFill
profileImage.contentMode = .scaleAspectFill
Keep in mind that using this contentMode option some portion of the content may be clipped to fill the view’s bounds.
You can set the Different Content Mode as per you choice from StoryBoard:
You can select
Scale to Fill
Aspect Fill
or any other content mode by using trial and Error method which suits you
Hope it Helps.
If I choose Aspect Fit, I'm getting blank space in top and bottom of the imageview.
Can I trim that space anyhow?
Is there any programatically constraints I can set to re-scale imageview according to actual image size?
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 want just this simple effect:
that I have a picture automatically orients itself according to the device/screen orientation, it alway fill up the whole screen without stretching itself so that the aspect doesn't change.
I work with Xcode though I got a lot of answer with storyboard and UI builder,I really don't like such ways that work well but you have no idea how it works, so I was trying to find the way to do it programmatically instead.
I've tried to set a image view as subview, but it doesn't fix well after the device is rotated, it either stretch to fill the screen or move to somewhere else with size unchanged (when I trie to recalculate the frame and apply to the subview), then I tried to override the drawrect func, of the UIView, the frame works fine but the animation of rotating is broken (it stretches it self during the rotation and then skip into the final frame).
the perfect effect I want is just like iOS original photo app, when I check a photo, it resizes to fix the screen, and even when I rotate the screen, the animation works just perfect, the rotating and scaling happens in the same time and no skip of stretch happens. could anyone please give me some help?
THANKS!!!!!
the way I set the frame:
func locating (imgsize:CGSize,scrsize:CGSize) ->CGRect {
var size:CGSize
var ori:CGPoint
if ((imgsize.height / imgsize.width) * scrsize.width>=scrsize.height){
size = CGSize(width:scrsize.width,height:imgsize.height*(scrsize.width/imgsize.width))
ori = CGPoint(x:0,y:scrsize.height-imgsize.height*(scrsize.width/imgsize.width))
}
else {
size = CGSize(width:imgsize.width*(scrsize.height/imgsize.height),height:scrsize.height)
ori = CGPoint(x:-(imgsize.width*(scrsize.height/imgsize.height)-scrsize.width)/2,y:0)
}
return CGRect(origin:ori,size:size)
}
Apart from math's stuff! here is also the solutions that can work for you!
Set image width and height to superview width and height.
self.imageView.frame = self.imageView.superView?.bounds
Then set your imageView's contentMode property to aspectFill or aspectFit
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
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)