How to set Dynamic Height of UIImage in UICollectionView Like Pinterest in Swift











up vote
-1
down vote

favorite












I am trying to do layout like Pinterest uses for their image gallery, but the issue is that I'm returning the image height to size the cells and when the images have different heights it leaves spaces in the cells. I have walked through lot's of articles, but I have not found a simple solution. Is there any simple way we can do this? Thanks you for your time and help!



Please see this image



class ViewController: UIViewController {

@IBOutlet var collectionVIew: UICollectionView!
var imgData = [#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8")]

override func viewDidLoad() {
super.viewDidLoad()

}


}

extension ViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
let img = imgData[indexPath.item]
// 335 is the width of my cell image
return CGSize(width: width/2-15, height: (img.size.height / 335) * width)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imgData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit
return cell
}
}









share|improve this question
























  • This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
    – cyril
    Nov 20 at 16:11










  • Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
    – Yogesh Patel
    Nov 20 at 16:17












  • @YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
    – DonMag
    Nov 20 at 16:30










  • There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
    – Damon
    Nov 20 at 16:31












  • Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
    – Yogesh Patel
    Nov 20 at 16:35















up vote
-1
down vote

favorite












I am trying to do layout like Pinterest uses for their image gallery, but the issue is that I'm returning the image height to size the cells and when the images have different heights it leaves spaces in the cells. I have walked through lot's of articles, but I have not found a simple solution. Is there any simple way we can do this? Thanks you for your time and help!



Please see this image



class ViewController: UIViewController {

@IBOutlet var collectionVIew: UICollectionView!
var imgData = [#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8")]

override func viewDidLoad() {
super.viewDidLoad()

}


}

extension ViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
let img = imgData[indexPath.item]
// 335 is the width of my cell image
return CGSize(width: width/2-15, height: (img.size.height / 335) * width)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imgData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit
return cell
}
}









share|improve this question
























  • This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
    – cyril
    Nov 20 at 16:11










  • Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
    – Yogesh Patel
    Nov 20 at 16:17












  • @YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
    – DonMag
    Nov 20 at 16:30










  • There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
    – Damon
    Nov 20 at 16:31












  • Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
    – Yogesh Patel
    Nov 20 at 16:35













up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











I am trying to do layout like Pinterest uses for their image gallery, but the issue is that I'm returning the image height to size the cells and when the images have different heights it leaves spaces in the cells. I have walked through lot's of articles, but I have not found a simple solution. Is there any simple way we can do this? Thanks you for your time and help!



Please see this image



class ViewController: UIViewController {

@IBOutlet var collectionVIew: UICollectionView!
var imgData = [#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8")]

override func viewDidLoad() {
super.viewDidLoad()

}


}

extension ViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
let img = imgData[indexPath.item]
// 335 is the width of my cell image
return CGSize(width: width/2-15, height: (img.size.height / 335) * width)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imgData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit
return cell
}
}









share|improve this question















I am trying to do layout like Pinterest uses for their image gallery, but the issue is that I'm returning the image height to size the cells and when the images have different heights it leaves spaces in the cells. I have walked through lot's of articles, but I have not found a simple solution. Is there any simple way we can do this? Thanks you for your time and help!



Please see this image



class ViewController: UIViewController {

@IBOutlet var collectionVIew: UICollectionView!
var imgData = [#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8")]

override func viewDidLoad() {
super.viewDidLoad()

}


}

extension ViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
let img = imgData[indexPath.item]
// 335 is the width of my cell image
return CGSize(width: width/2-15, height: (img.size.height / 335) * width)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imgData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit
return cell
}
}






ios swift uicollectionview uicollectionviewflowlayout






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 at 14:35









rmaddy

237k27308375




237k27308375










asked Nov 20 at 16:03









Yogesh Patel

138




138












  • This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
    – cyril
    Nov 20 at 16:11










  • Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
    – Yogesh Patel
    Nov 20 at 16:17












  • @YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
    – DonMag
    Nov 20 at 16:30










  • There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
    – Damon
    Nov 20 at 16:31












  • Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
    – Yogesh Patel
    Nov 20 at 16:35


















  • This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
    – cyril
    Nov 20 at 16:11










  • Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
    – Yogesh Patel
    Nov 20 at 16:17












  • @YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
    – DonMag
    Nov 20 at 16:30










  • There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
    – Damon
    Nov 20 at 16:31












  • Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
    – Yogesh Patel
    Nov 20 at 16:35
















This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
– cyril
Nov 20 at 16:11




This might not be a direct answer to your question, but here's a great resource for you to learn to do just that: google.com/…
– cyril
Nov 20 at 16:11












Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
– Yogesh Patel
Nov 20 at 16:17






Yes i see this article but the trick they use is too complex for me is there is another way we can achieved this thing then please tell me ?
– Yogesh Patel
Nov 20 at 16:17














@YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
– DonMag
Nov 20 at 16:30




@YogeshPatel - "the trick they use" is much better phrased as the code they wrote. That article is a complete walk-through tutorial answering your question -- Like Pinterest in Swift. If you really want to do a Pinterest style layout, you can't find much of a better resource than that article. raywenderlich.com/…
– DonMag
Nov 20 at 16:30












There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
– Damon
Nov 20 at 16:31






There is no easy way out. You will have to implement your own custom UICollectionViewLayout. Create your own custom layout. Set the attributes and assign that layout to your Collection View.
– Damon
Nov 20 at 16:31














Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
– Yogesh Patel
Nov 20 at 16:35




Yes you suggest this article is best but can we achieved this in less code and simple solution .? like calculate the y position and height of the 1 image that the position of height is the y of 3 image .?
– Yogesh Patel
Nov 20 at 16:35












2 Answers
2






active

oldest

votes

















up vote
0
down vote













You are trying to fit non-square images into a square hole. When we do this something has to give. In this case I would recommend you make each of your cells a fixed height and set an aspect fill content mode on them so they fill the cell's frame completely. The downside is that some of the larger images will have part of them cut off. The other option is to use the aspect fit content mode which will scale the image to fit without losing a part of the image. This would leave you with the cell spacing again.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
return cell
}


Alternatively, you can checkout some open source libraries that might implement this for you. This one looks promising https://github.com/abdullahselek/ASCollectionView



You can checkout a larger list of collection view open source libraries here https://github.com/vsouza/awesome-ios#collection-view



If you want the cells to have different heights you need to calculate the correct hight based off of the aspect ratio of the image and the width that is fixed. You calculate the aspect ratio in this case by the height / width when our width is fixed and our height is dynamic. Then multiply that by the width of the cell of the image to get our dynamic cell height.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width / 2 - 15;
let img = imgData[indexPath.item]
return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}


You should set your content mode to aspect fit in this case.



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
return cell
}





share|improve this answer























  • Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
    – Yogesh Patel
    Nov 20 at 16:23










  • Thanks For Library but can we do this thing without library .?
    – Yogesh Patel
    Nov 20 at 16:28










  • Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
    – Allen R
    Nov 20 at 22:08












  • Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
    – Yogesh Patel
    Nov 21 at 1:37












  • it's not working some extra space are there in cell image
    – Yogesh Patel
    Nov 21 at 2:01




















up vote
-1
down vote













What you have mentioned can be achieved using flow layout — a layout class provided by UIKit.



This is what you are looking for:



https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest



I hope you can put some effort into reading this very simple post and follow each step carefully.






share|improve this answer























  • Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
    – Yogesh Patel
    Nov 20 at 16:36










  • @Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
    – Damon
    Nov 20 at 16:38










  • NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
    – Satish
    Nov 20 at 16:39










  • ok thank You i follow this article and trying to understand this !
    – Yogesh Patel
    Nov 20 at 16:43











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396952%2fhow-to-set-dynamic-height-of-uiimage-in-uicollectionview-like-pinterest-in-swift%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













You are trying to fit non-square images into a square hole. When we do this something has to give. In this case I would recommend you make each of your cells a fixed height and set an aspect fill content mode on them so they fill the cell's frame completely. The downside is that some of the larger images will have part of them cut off. The other option is to use the aspect fit content mode which will scale the image to fit without losing a part of the image. This would leave you with the cell spacing again.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
return cell
}


Alternatively, you can checkout some open source libraries that might implement this for you. This one looks promising https://github.com/abdullahselek/ASCollectionView



You can checkout a larger list of collection view open source libraries here https://github.com/vsouza/awesome-ios#collection-view



If you want the cells to have different heights you need to calculate the correct hight based off of the aspect ratio of the image and the width that is fixed. You calculate the aspect ratio in this case by the height / width when our width is fixed and our height is dynamic. Then multiply that by the width of the cell of the image to get our dynamic cell height.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width / 2 - 15;
let img = imgData[indexPath.item]
return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}


You should set your content mode to aspect fit in this case.



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
return cell
}





share|improve this answer























  • Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
    – Yogesh Patel
    Nov 20 at 16:23










  • Thanks For Library but can we do this thing without library .?
    – Yogesh Patel
    Nov 20 at 16:28










  • Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
    – Allen R
    Nov 20 at 22:08












  • Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
    – Yogesh Patel
    Nov 21 at 1:37












  • it's not working some extra space are there in cell image
    – Yogesh Patel
    Nov 21 at 2:01

















up vote
0
down vote













You are trying to fit non-square images into a square hole. When we do this something has to give. In this case I would recommend you make each of your cells a fixed height and set an aspect fill content mode on them so they fill the cell's frame completely. The downside is that some of the larger images will have part of them cut off. The other option is to use the aspect fit content mode which will scale the image to fit without losing a part of the image. This would leave you with the cell spacing again.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
return cell
}


Alternatively, you can checkout some open source libraries that might implement this for you. This one looks promising https://github.com/abdullahselek/ASCollectionView



You can checkout a larger list of collection view open source libraries here https://github.com/vsouza/awesome-ios#collection-view



If you want the cells to have different heights you need to calculate the correct hight based off of the aspect ratio of the image and the width that is fixed. You calculate the aspect ratio in this case by the height / width when our width is fixed and our height is dynamic. Then multiply that by the width of the cell of the image to get our dynamic cell height.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width / 2 - 15;
let img = imgData[indexPath.item]
return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}


You should set your content mode to aspect fit in this case.



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
return cell
}





share|improve this answer























  • Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
    – Yogesh Patel
    Nov 20 at 16:23










  • Thanks For Library but can we do this thing without library .?
    – Yogesh Patel
    Nov 20 at 16:28










  • Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
    – Allen R
    Nov 20 at 22:08












  • Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
    – Yogesh Patel
    Nov 21 at 1:37












  • it's not working some extra space are there in cell image
    – Yogesh Patel
    Nov 21 at 2:01















up vote
0
down vote










up vote
0
down vote









You are trying to fit non-square images into a square hole. When we do this something has to give. In this case I would recommend you make each of your cells a fixed height and set an aspect fill content mode on them so they fill the cell's frame completely. The downside is that some of the larger images will have part of them cut off. The other option is to use the aspect fit content mode which will scale the image to fit without losing a part of the image. This would leave you with the cell spacing again.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
return cell
}


Alternatively, you can checkout some open source libraries that might implement this for you. This one looks promising https://github.com/abdullahselek/ASCollectionView



You can checkout a larger list of collection view open source libraries here https://github.com/vsouza/awesome-ios#collection-view



If you want the cells to have different heights you need to calculate the correct hight based off of the aspect ratio of the image and the width that is fixed. You calculate the aspect ratio in this case by the height / width when our width is fixed and our height is dynamic. Then multiply that by the width of the cell of the image to get our dynamic cell height.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width / 2 - 15;
let img = imgData[indexPath.item]
return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}


You should set your content mode to aspect fit in this case.



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
return cell
}





share|improve this answer














You are trying to fit non-square images into a square hole. When we do this something has to give. In this case I would recommend you make each of your cells a fixed height and set an aspect fill content mode on them so they fill the cell's frame completely. The downside is that some of the larger images will have part of them cut off. The other option is to use the aspect fit content mode which will scale the image to fit without losing a part of the image. This would leave you with the cell spacing again.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width
return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
return cell
}


Alternatively, you can checkout some open source libraries that might implement this for you. This one looks promising https://github.com/abdullahselek/ASCollectionView



You can checkout a larger list of collection view open source libraries here https://github.com/vsouza/awesome-ios#collection-view



If you want the cells to have different heights you need to calculate the correct hight based off of the aspect ratio of the image and the width that is fixed. You calculate the aspect ratio in this case by the height / width when our width is fixed and our height is dynamic. Then multiply that by the width of the cell of the image to get our dynamic cell height.



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.size.width / 2 - 15;
let img = imgData[indexPath.item]
return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}


You should set your content mode to aspect fit in this case.



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imgView.image = imgData[indexPath.row];
cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
return cell
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 21 at 2:04

























answered Nov 20 at 16:19









Allen R

826517




826517












  • Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
    – Yogesh Patel
    Nov 20 at 16:23










  • Thanks For Library but can we do this thing without library .?
    – Yogesh Patel
    Nov 20 at 16:28










  • Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
    – Allen R
    Nov 20 at 22:08












  • Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
    – Yogesh Patel
    Nov 21 at 1:37












  • it's not working some extra space are there in cell image
    – Yogesh Patel
    Nov 21 at 2:01




















  • Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
    – Yogesh Patel
    Nov 20 at 16:23










  • Thanks For Library but can we do this thing without library .?
    – Yogesh Patel
    Nov 20 at 16:28










  • Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
    – Allen R
    Nov 20 at 22:08












  • Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
    – Yogesh Patel
    Nov 21 at 1:37












  • it's not working some extra space are there in cell image
    – Yogesh Patel
    Nov 21 at 2:01


















Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
– Yogesh Patel
Nov 20 at 16:23




Thanks For Your Response, with your solution if i fixed the height then the output is not like Pinterest it like gallery
– Yogesh Patel
Nov 20 at 16:23












Thanks For Library but can we do this thing without library .?
– Yogesh Patel
Nov 20 at 16:28




Thanks For Library but can we do this thing without library .?
– Yogesh Patel
Nov 20 at 16:28












Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
– Allen R
Nov 20 at 22:08






Of course you can do it without a library. Libraries just make things easier for us. I have added another section that should help. @YogeshPatel
– Allen R
Nov 20 at 22:08














Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
– Yogesh Patel
Nov 21 at 1:37






Hello (img.size.height / image.size.width) * width . img i got and devided by which image ??
– Yogesh Patel
Nov 21 at 1:37














it's not working some extra space are there in cell image
– Yogesh Patel
Nov 21 at 2:01






it's not working some extra space are there in cell image
– Yogesh Patel
Nov 21 at 2:01














up vote
-1
down vote













What you have mentioned can be achieved using flow layout — a layout class provided by UIKit.



This is what you are looking for:



https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest



I hope you can put some effort into reading this very simple post and follow each step carefully.






share|improve this answer























  • Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
    – Yogesh Patel
    Nov 20 at 16:36










  • @Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
    – Damon
    Nov 20 at 16:38










  • NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
    – Satish
    Nov 20 at 16:39










  • ok thank You i follow this article and trying to understand this !
    – Yogesh Patel
    Nov 20 at 16:43















up vote
-1
down vote













What you have mentioned can be achieved using flow layout — a layout class provided by UIKit.



This is what you are looking for:



https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest



I hope you can put some effort into reading this very simple post and follow each step carefully.






share|improve this answer























  • Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
    – Yogesh Patel
    Nov 20 at 16:36










  • @Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
    – Damon
    Nov 20 at 16:38










  • NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
    – Satish
    Nov 20 at 16:39










  • ok thank You i follow this article and trying to understand this !
    – Yogesh Patel
    Nov 20 at 16:43













up vote
-1
down vote










up vote
-1
down vote









What you have mentioned can be achieved using flow layout — a layout class provided by UIKit.



This is what you are looking for:



https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest



I hope you can put some effort into reading this very simple post and follow each step carefully.






share|improve this answer














What you have mentioned can be achieved using flow layout — a layout class provided by UIKit.



This is what you are looking for:



https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest



I hope you can put some effort into reading this very simple post and follow each step carefully.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 at 16:37

























answered Nov 20 at 16:33









Satish

1,006615




1,006615












  • Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
    – Yogesh Patel
    Nov 20 at 16:36










  • @Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
    – Damon
    Nov 20 at 16:38










  • NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
    – Satish
    Nov 20 at 16:39










  • ok thank You i follow this article and trying to understand this !
    – Yogesh Patel
    Nov 20 at 16:43


















  • Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
    – Yogesh Patel
    Nov 20 at 16:36










  • @Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
    – Damon
    Nov 20 at 16:38










  • NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
    – Satish
    Nov 20 at 16:39










  • ok thank You i follow this article and trying to understand this !
    – Yogesh Patel
    Nov 20 at 16:43
















Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
– Yogesh Patel
Nov 20 at 16:36




Thanks For Your Response, can we do same thing in less code with simple solution .? with out third party library
– Yogesh Patel
Nov 20 at 16:36












@Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
– Damon
Nov 20 at 16:38




@Satish Flow layout will not be sufficient in this case. A custom layout will be needed.
– Damon
Nov 20 at 16:38












NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
– Satish
Nov 20 at 16:39




NO, you should put some effort into it, why someone will provide you the cooked code. Go somewhere you can find a freelancer, and pay some amount to him for this work.
– Satish
Nov 20 at 16:39












ok thank You i follow this article and trying to understand this !
– Yogesh Patel
Nov 20 at 16:43




ok thank You i follow this article and trying to understand this !
– Yogesh Patel
Nov 20 at 16:43


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396952%2fhow-to-set-dynamic-height-of-uiimage-in-uicollectionview-like-pinterest-in-swift%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'