How to set UICollectionViewCell height to 90% of the View (Screen) height? - swift

I'm trying to set the UICollectionViewCell height as 90% of the screen size. So the cell size would look good when using different devices.
The problem is that I'm not sure how to set the cell height programmatically. All cell should look the same size, so there's no need to consider the content, I only want the cell height to be 90% of the screen.
Here is what it looks like in iphone 6 screen:
However, when switching to a smaller device it looks like this:
Thank you in advance for your help!

You can set your UICollectionView's flow layout tile size programmatically. There are a couple of different places you could cause this, I would start with viewWillAppear (in your ViewController class) for starters:
override func viewWillAppear() {
super.viewWillAppear()
if let layout = self.schedulesView.collectionViewLayout as? UICollectionViewFlowLayout {
var cellSize = UIScreen.main.bounds.size // start with the full screen size
cellSize.height *= 0.9 // adjust the height by 90%
layout.itemSize = cellSize // set the layouts item size
}
}

You can set collectionView itemSize by using collectionViewFlowLayout according to device size. Try below method..
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
// All the values are changable according to your needs.
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.sectionInset = UIEdgeInsets(top: 25, left: 3, bottom: 3, right: 3)
layout.minimumInteritemSpacing = 50
layout.minimumLineSpacing = 50
return CGSize(width: self.collectionView.frame.width - 50, height:self.collectionView.frame.height - 100)
}
Note: From the above code you will get box type collectionView itemSize that covers the view accordingly to device size.

Just figured what the problem is with contents inside UICollectionViewCell not updating their size.
Just need to as this to the subclass of UICollectionViewCell
override var bounds: CGRect {
didSet {
contentView.frame = bounds
}
}

Related

Auto-Layout for CollectionViewCell: Trailing/Leading constraints change cell size

I just can´t get familar with auto layout in Xcode. When I set trailing and leading constrains for Header Stack View, Bottom Stack View or the image between them, then the size (height/width) of my cell changes. Why does it happen and how can I avoid it? I think something isn´t right with the kind I build layouts. I am very grateful for any help.
I set the cell size with this code:
extension MainVC: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = view.frame.size.height
let width = view.frame.size.width
return CGSize(width: width * 0.42, height: height * 0.3)
}
}
My cell layout:
This is how the app looks when I use constrains for the Bottom Stack View.
This is without constrains for the Bottom Stack View (correct cell size).
Cells can now self-size with auto layout and ignore what you return in collectionView(_:layout:sizeForItemAt:). If you want to use collectionView(_:layout:sizeForItemAt:), change Estimate size to None in the storyboard.
https://stackoverflow.com/a/58369142/14351818

Need to move the cell inside the uicollectionview cell && Textfield image adding

need to move the collection view cell accordingly. I have attached my screenshot for your reference:
the above is my current image but I need that to be like this:
Then I need to add image to the textfield but I have added some code but I could not add it
searchtextfield.leftViewMode = UITextFieldViewMode.always
searchtextfield.leftView = UIImageView(image: UIImage(named: "search"))
For the collection view cell width and height you have to use below method:
extension "Your Controller" : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width/2 - 15, height: collectionView.frame.size.width/2 - 15)
}
}
To make the the cell square I have added the with and height same. You can change it according to your requirement. The collection view width changes for different devices so you have to change the cell width and height too.
Don't forget to do the change in this too according to your requirement:
Hope this helps.

Image does not fit properly in collectionCell

In Swift 3. My app has a table view and a detail view with is a view controller. Here I added a collection view. An array of images must be presented. The images adapt themselves beautifully if in portrait I check the content mode in scaler to fill. In ladscape it works in aspectFill. Vice-versa, the layout does not fit. I did the following
in cellForItem At:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = myCollection.dequeueReusableCell(withReuseIdentifier: "cellCollection", for: indexPath) as! CollectionViewCell
cell.cellImage.image = UIImage(named: array[indexPath.item])
if UIDevice.current.orientation.isLandscape{
cell.cellImage.contentMode = .scaleAspectFill
}
else if UIDevice.current.orientation.isPortrait{
cell.cellImage.contentMode = .scaleToFill
}
return cell
}
It does not work. May be I have some inconsistencies from portrait to landscape.
I would appreciate your help. If you want to take a look at the project in git:
[https://github.com/ricardovaldes/tareaFinalHoteles.git1. Thanks in advance.
Eureka. Finally I did solve this problem. With sizeForItem at, the app could function without problems. I was lost or mislead looking for a way to change the image content mode, but this is not the right way. The correct way is resize once you rotate: for this you need the func willTransition toNewCollection: UITraitCollection. Inside you create a variable layout that is of type UICollectionViewFlowLayout. With the help of a conditional, is possible to define how you want the with and heigt after rotation.This post is clear and concise for those curious: UICollectionView Cell Resizing on Device Rotation.
Here the implementation I did in my project: `
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape,
let layout = myCollection.collectionViewLayout as? UICollectionViewFlowLayout{
let with = myCollection.frame.size.width
layout.itemSize = CGSize(width: with, height: 280)
layout.invalidateLayout()
}
else if UIDevice.current.orientation.isLandscape,
let layout = myCollection.collectionViewLayout as? UICollectionViewFlowLayout{
let with = myCollection.frame.size.width
layout.itemSize = CGSize(width: with/2, height: 280)

How to align collectionview cells right next to each other?

I am creating a profile page screen for my application. The screen displays all the user's recent posts. I used storyboard to create two UICollectionViewCells in a UICollectionView, one that displays your profile info and the other that displays your posts. See this for how I designed it in storyboard: https://i.stack.imgur.com/6TzwK.png
When I run the application, I get the following result: https://i.stack.imgur.com/XmvY3.jpg
However, I desire the cells placed in a way that it looks like the following: https://i.stack.imgur.com/nWQ14.jpg
How do I force the cells the align so it looks like the image above? Thanks!
Found an answer to the question. Implement UICollectionViewDelegateFlowLayout delegate to your class. Then, include the following method into the class:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = UIScreen.main.bounds.width // get the width of the screen
let scale = (width / 3) // get the width (and height) of each cell
if indexPath.row != 0 { // check to see if the cell is the profile header
return CGSize(width: scale, height: scale) // if not, then return the cell size
}
return CGSize(width: width, height: ((238/414) * width)) // if it is the profile header, return the size for it.
}
Make sure "Min Spacing" for the UICollectionView's storyboard setting to 0,0. The cells will then align into a grid view.

UICollectionView chat bubble size

I am currently working at a chat app in Xcode 9. I am not using stroyboards doing everything programmatically. For the "chat room" I am using a UICollectionViewController and I want the cells to adjust to the size of the text. I am calculating the size of the cells like that:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let size = CGSize(width: 250, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
let estimatedFrame = NSString(string: messages[indexPath.item].content as! String).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 18)], context: nil)
return CGSize(width: view.frame.width, height: estimatedFrame.height + 45)
}
So I am basically just calculating the size of the text and then return it as the cells hight. This works fine with short texts, but as soon as the text is longer than 6 lines, the last line is missing. From that point the calculated height is just wrong, because if I just set a constant height, the text shows. Can anyone spot a mistake or should I just use another method to get self sizing chat bubbles in a UICollectionView?