I have used AutoLayout with one of my UICollectionView I'm facing issue with height and width for imageView. I have added UIImageView in my UICollectionViewCell like following with below constraints.
UICollectionViewDataSource methods.
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var width = Int((collectionView.frame.size.width - 30) / 4)
if width % 2 != 0 {
width += 1
}
return CGSize(width: CGFloat(width), height: CGFloat(width))
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
print("Cell Size - \(cell.bounds)")
print("ImageView Size - \(cell.imageView.frame)")
return cell
}
But when I run this the ImageView is always coming with 70X70 no matter on which device I will run but UICollectionViewCell size is increasing and decreasing on different devices.
On iPhone 6 it will looks like below.
I have set backgroundColor of UIImageView to white color and red color for UICollectionViewCell so that it will give batter understanding the console log for Cell and ImageView Size is as below.
Cell Size - (0.0, 0.0, 86.0, 86.0)
ImageView Size - (5.0, 5.0, 70.0, 70.0)
Cell Size - (0.0, 0.0, 86.0, 86.0)
ImageView Size - (5.0, 5.0, 70.0, 70.0)
Please any one help me why the imageView size is not increasing or decreasing according to the UICollectionViewCell. Any help would be appreciated.
in size inspector of collection view ,set Estimate Size to None
After researching a bit I have came up with the following way to solved this issue of AutoLayout with UICollectionViewCell. From Xcode 6 CollectionViewCell doesn't show the contentView in interface builder, so in the awakeFromNib of cell I have set its autoresizingMask and it works like charm.
class CustomCell: UICollectionViewCell {
#IBOutlet
var imageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
//Below line solved my problem
self.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
}
}
you need to set constraints as below screenshot;
Center horizontally and Center vertically Constraints should not be there when pin to parent all the sides(Top,Bottom,Leading & Trailing) were given for your Image view.
Either remove Center horizontally and Center vertically Constraints
Or Top,Bottom,Leading & Trailing and give equal widths and heights as parent along with centre vertically and horizontally.
Seems removing Center horizontally and Center vertically Constraints will solve your problem for sure,give it a try.
Hope that helps.
Good luck.
Related
How to increase the UICollectionView Cell width & height equal to screen in swift 4.2 ?
Provided your UICollectionViewCell has a subview of UIImageView that is anchored to fill it completely(i.e. UIImageView is anchored UICollectionViewCell in top, bottom, left and right manner).
The following method can be used to size the UICollectionViewCell in accordance to the screen screen holding it, this will automatically result in the UIImageView being as big as the screen itself.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return self.collectionView.bounds.size //to ensure that this works as intended set self.collectionView size be the screen size.
}
Please note that the UICollectionView is big enough to hold the size of the UICollectionViewCell that you seek.
You need to change your cell size to fit the collectionview. Add this in viewDidLoad
if let flow = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flow.itemSize = self.collectionView.frame.size
}
I'm having a hard time with auto layout and UICollectionView. I have a vertical UICollectionVIewFlowLayout that contains two different types of cells, as in the image below:
The SingleCard cell contains a subview with an image (UIImageView). The HorizList cell contains a subview which is a horizontal UICollectionView (a list of thumbnail photos). The heights of the two cell types are as follows:
SingleCard: the width of the cell shall be the same as the screen width. The height shall be dynamic to the height of the UIImageView (to keep proportions of the image and have it fill screen width no matter of device size)
HorizList: the height is constant, say 200 points.
My attempt, in the CollectionViewController is to do
override func viewDidLoad() {
...
let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
layout.estimatedItemSize = CGSize(width: 200.0, height: 235.0)
}
This I do to get the two cell's intrinsic size to apply. Then I do not implement
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
at all.
My question is, what do I implement in
override var intrinsicContentSize: CGSize {
??
}
for the two different cell types? Maybe this is not the only thing I need to do, if so I'm grateful for additional hints.
Thanks!
/ola
I have spent 3 days of searching and reading. In my IOS app I have a custom Cell for UICollectionView with xib File. In this custom cell I have 3 labels, images and buttons. 1 label from it is in the middle and always gets different sizes because it's multiline.
So I must calculate all items height. It's not the problem but the problem is only with this one multiline label. So I want calculate the size for each cell and get the size for sizeForItemAtIndexPath in UICollectionViewController.
After 3 days I think I cannot access this. Can I do this from the custom cell class? If yes, how? If I can access it in UICollectionViewController, how?
//MARK: - CollectionView Flow Layout
extension PhotosCollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let viewSize = super.view.bounds.size
let spacing: CGFloat = 0.5
let width = (viewSize.width) - spacing - 10
/*
Here I need my cell with label name "Beschreibungstext"
to calculate the hight from the label with help from rectangle.
return CGSize(width: width, height: customhight)
*/
return CGSize(width: width, height: CGFloat(400))
}
}
I am using a collection view to display a collection of profile images and the person's name. So my cell has a UIImageView and a UILabel as subviews. I am using the UICollectionViewDelegateFlowLayout method:
collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
to calculate the cell's size depending on the available space.
All of this is working fine. I have added constraints to my subviews in the cell so that they also resize accordingly.
The issue I am running into is that I want my UIImageViews to be circles. It seems like auto layout is not recalculating the cell's subview size until after I have applied that effect. Instead, when I calculate the cornerRadius for the imageView it is still saying the imageViews width is 114.0 (which is what is in the storyboard) regardless of how big the cell is. This results in circles on the iPhone 5s but only rounded corners on any bigger device. Here is my code for that:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("PersonCell", forIndexPath: indexPath)
configureCell(cell, atIndexPath: indexPath)
return cell
}
func configureCell(cell: UICollectionViewCell, atIndexPath indexPath: NSIndexPath) {
if let person = personAtIndexPath(indexPath) {
let imageView = cell.viewWithTag(100) as! UIImageView
let nameLabel = cell.viewWithTag(200) as! UILabel
cell.contentView.frame = cell.bounds
cell.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
circularizeImageView(imageView)
imageView.image = person.profileImage
nameLabel.text = person.name
}
}
func circularizeImageView(imageView: UIImageView) {
imageView.layer.cornerRadius = (CGRectGetWidth(imageView.bounds) / 2)
imageView.clipsToBounds = true
imageView.layer.borderWidth = 2.0
imageView.layer.borderColor = UIColor.whiteColor().CGColor
}
I saw in a couple places that previously the subviews would not resize at all like here: UICollectionView cell subviews do not resize
I don't think this is an issue any more, however I did add the fixes into my code as you can see in configureCell() but it still isn't helping.
So it seems like those subviews are not resized until after the cellForItemAtIndexPath call is completed. Any thoughts on how I might address this? See screenshot of :rounded corners on UIImageViews instead of complete circles
Don't use viewWithTag(), it's bad practice. Instead make the UILabel and UIImageView public or leave off the scope modifier.
Is the UIImageView a fixed size? If so, you don't need to call circularizeImageView() each time a cell is reused. Instead, call it in layoutSubviews() in your UITableViewCell subclass. This will also give you the correct size for imageView.bounds.height
I have a collectionView with horizontal UICollectionViewFlowLayout.
I am trying to achieve:
If a device orientation is portrait, UIImageView width will be qual to view.width and let the height be calculated automatically (like it usually happens with Auto Layout). And the same for the landscape mode. Example - standard photo app on the Iphone.
Unfortunately i don't see how to achieve it with autoLayout. I set constraints on UIImageView for it to be equal in size to the cell. But looks like the sell itself cannot be pinned to the Parent View.
After reading similar questions looks like cells must be resized programmatically using
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: width, height: height)
}
And here i am stuck because i know the width of the screen but don't know how to calculate the height dynamically.
About image height:
I have my image declared like this:
var pageImages = [UIImage]()
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: ImageDetailViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! ImageDetailViewCell
let curr = indexPath.row
let imgName = data[albumNumber][curr]["image"]
cell.DetailImageView.image = UIImage(named: imgName!)
return cell
}
If you use the proper UIImageView resize setting (say, aspect fit/fill), then you just need to set the cell's height to your collectionView's (you get a pointer to it as one of the ...sizeForItemAtIndexPath... method parameters) height. You also should call the - layoutIfNeeded method on your cell afterwards.
You can use sizeForItemAtIndexPath: to change the size of collection view cell.
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var numberOfCellInRow : Int = 3
var padding : Int = 5
var collectionCellWidth : CGFloat = (self.view.frame.size.width/CGFloat(numberOfCellInRow)) - CGFloat(padding)
return CGSize(width: collectionCellWidth , height: collectionCellWidth)
}
You can get the size of cell via :
((UICollectionViewFlowLayout) self.collectionViewName).itemSize.height)
You can get the image size via :
let sizeOfImage = image.size
let height = image.height
If you want to change the height then change it manually by return CGSize(width: collectionCellWidth , height: cellheight)