How to add many UIImageViews inside ScrollView? - ios

I will have about 12+ (any multiple of 4 per row) images that I want to have inside a ScrollView. See example below, the 12 circles (with the last row cut off a bit) are the UIImageViews.
I am not able to add the UIImageViews inside the ScrollView. The width,height of the scrollView is 250,250
This is what I have tried:
func setScrollView() {
scrollView_avatars.contentSize = CGSizeMake(250,300);
let imgView1: UIImageView = UIImageView(image: UIImage(named: "img1.jpg"))
let imgView2: UIImageView = UIImageView(image: UIImage(named: "img2.jpg"))
let imgView3: UIImageView = UIImageView(image: UIImage(named: "img3.jpg"))
scrollView_avatars.addSubview(imgView1)
scrollView_avatars.addSubview(imgView2)
scrollView_avatars.addSubview(imgView3)
}
iOS noob here
My code above gives me very bizarre output, i think the sizes of the UIImageViews are not set correctly.
I dont also know how to position the UIImageViews within the ScrollView like only part of a image is visible.

As #rmaddy says, you need to set the frame properties on your views. You will need to do math to calculate their positions based on row/column position in your grid of views.
If you're using AutoLayout you may need to generate constraints to set the view's sizes and positions. (I haven't tried to add views to a scroll view in code with AutoLayout before, so I'm not totally positive what happens if you just set their frames without defining constraints.)

You need to declare your image views like this:
if let image = UIImage(named: "myImage"){
let imageView = UIImageView(frame: CGRectMake(yourXpoint, yourYpoint, image.size.width, image.size.height))
imageView.image = image
}
where yourXpoint and yourYpoint is where you want the image origin to be set, this way you are saying to swift where do you want the images to be place and what is its size.
The if let is just to be safe in case the image does not exist.
Another good option is to set constrains as it will make your app have a nice layout in al different screen sizes and orientation

Related

UICollectionViewCell with a dynamic image dimensions - As u scroll, the image loses its initial constraints when the cell is re-used TestApp attached

I would like some assistance please.
I have a UICollectionViewCell for an onBoarding scenario each cell contains one image with different dimensions that are set dynamically.
I am using WWLayout similar to SnapKit to handle the constrains.
The issue is when I swipe thru and the cell is re-used the constraints break and the image loses its initial dimensions.
I have attached a TestApp.
https://www.dropbox.com/s/tx141lpr0uzlhbx/Test%20App.Image.Resize.zip?dl=0
Thank you.
In OnBoardingItemView.swift, function layoutUI(), just before you layout imageView, try adding this line:
imageView.removeConstraints(imageView.constraints)
The image was not being scaled properly. Update your code with this one to prevent the image from stretching.
private lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
This variable is in OnBoardingItemView.swift, line 35

When I click the cell, the image is stretch out

This is the cell I created by XIB:
But however, after I use tableView load the cells, I get the issue:
You need to change image scale as below :
imageView.contentMode = UIViewContentModeScaleAspectFit;
Swift 3
imageView.contentMode = .scaleAspectFit
It is because you used Aspect Fill in the attribute pannel. Thus the image width equal to the screen (as per your constraints) and keep its width*height ratio, but it is going outside bounds of your imageView.
You need to add in viewDidLoad or in your class file:
imageView.clipsToBounds = true
Check this link to Apple's documentations
you need to clip the image out side bounds:
imageView.clipsToBounds = YES
it will crop image to visible rect only
If you design your cell in xib, you can set the Clip to Bounds in Drawing:

ios Custom UIButton scale setImage down not working

I have problem in scale down setImage size if I add UIButton by programmatically whereas if I add the UIButton by storyboard, the UIButton size remain correctly.
The Image is 128x128, I want to shrink down to 30x30
Top one is created from using storyboard, Bottom is created from using programmatically
These are the methods I tried, none able to shrink the image...
let checkBox = UIButton(type .system)
checkBox.sizeThatFits(CGSize(width: 30, height: 30))
checkBox.contentMode = .scaleAspectFit
checkBox.contentVerticalAlignment = .fill
checkBox.contentHorizontalAlignment = .fill
checkBox.heightAnchor.constraint(equalToConstant: 15.0)
checkBox.widthAnchor.constraint(equalToConstant: 15.0)
Image is set/update on runtime
checkBox.setImage(UImage, for: .normal)
With suggest using checkBox.frame.size.width, checkBox.frame.size.height
the image becomes correct size but the UIButton now have extra space.
Like the image below. I update image on touchUP UIButton
What about this:
checkBox.frame.size.width = 30
checkBox.frame.size.height = 30
The Image is 128x128, I want to shrink down to 30x30
One obvious solution, in that case, is to shrink the image. Redraw the image into a 30x30 graphics context at 30x30 size and extract the resulting image. Now you have a 30x30 image. That's the best way; it is a waste of memory to hand the runtime a way oversized image and ask it to display it smaller.
Now, if you want to use constraints to size and position the button, that's fine, but you are not doing that correctly. First, you have forgotten to set the button's translatesAutoresizingMaskIntoConstraints to false. Second, you have to supply enough constraints not only to set the button's height and width but also its horizontal and vertical position.

How to fill the background image in a UIView without streching it

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

Why UIImageView's image can extend beyond itself?

Previously, i thought UIImageView's image cannot extend beyond the view. However, recently i read the book Programming in IOS8, it says:
You should also pay attention to a UIImageView’s clipsToBounds property; if it is false, its image, even if it is larger than the image view and even if it is not scaled down by the contentMode, may be displayed in its entirety, extending beyond the image view itself.
And then i did some simple test, that's true.
Here is the question: What's the purpose for Apple to design UIImageView with this feature? I, for now, cannot find the advantage of it. I think this makes contentMode a fake property.
Here is an example:
It is a refreshView with customized pull-to-refresh animation above in a UITableView. I set up a UIImageView with the same size as the refreshView and add it as a background view. Relevant code here:
let imgView = UIImageView()
imgView.frame = self.bounds
imgView.image = UIImage(named: "refresh-view-bg.png")
imgView.contentMode = .ScaleAspectFill
imgView.clipsToBounds = true
self.addSubview(imgView)
It works fine:
However, when i annotate this line:
imgView.clipsToBounds = true
It turns like that:
The image extend beyond the UIImageView
ps: I'm not using autoLayout in this demo
This is due to autolayout. UIImageView returns its -intrinsicContentSize by the calculation of image size. If you want to avoid that you should set a width (or height) constraints, or play with content hugging/compression resistance priorities if you want to share or not the space when you view is laid out with other views around.

Resources