This has been asked several times and I have tried to include aspects of all answers in my code - which still does not work - so there may be issues with methods/characteristics becoming obsolete in the newest iOS or with me just doing things wrong. But here is where I'm at:
The teal is background color for the CollectionView. Then there is a PostCell with a pink background which is covered with a blue image view on top of it to which I set an image from a url (the video thumbnail on top) as well as a pink textView containing notes.
What I want is to make the PostCell adhere to the top and bottom of the collection View so that you can no longer see the teal section.
Here are the constraints I have set as well as the view hierarchy:
In my TagViewController - the controller for this view, I have:
class TagViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
....
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
//top, left, bottom, right
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
collectionView.contentInsetAdjustmentBehavior = .never
}
....
}
The insetForSectionAt method and the methods I set in viewDidLoad are from the answers to similar questions I have found on stackOverflow so far such as here: UICollectionView adds top margin
and here:
iOS:Setting UICollectionView cell to view size
Have you tried the 'sizeForItemAt indexPath' method ?
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:
UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height)
}
Related
Im trying to get rounded UICollection cell but i found out that it's not working somehow and I can't come up why. I have a TableView in regular ViewController, in this tableview i've a custom table cell (in specified section) and in this custom table cell I've a CollectionView also with custom collectionCell and if i do anything rounded there, it's just not rounding anything. I cliped testBtn into bounds, but it wasn't work with this... I also tried testBtn.layer.masksToBounds with no success. However, if I'am doing a rounding in parent (tableView cell itself), it's working just good...
CollectionViewCell code:
import UIKit
class ProfileTileCollectionViewCell: UICollectionViewCell {
#IBOutlet var testBtn: UIButton!
#IBOutlet var contView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
testBtn.layer.cornerRadius = 20
testBtn.clipsToBounds = true
// Initialization code
}
#IBAction func testClicked(_ sender: Any) {
print("clicked")
}
}
Screenshot of the mainView: Screenshot.png
Blue color is a background of collectionView, gray is background of cell and violet is a button. I don't know if it's getting late but it's weird for me, not be able to get working this thing... I'm missing something... Any help I will appreciate !
Try to set testBtn.layer.masksToBounds = true
From the screenshot, I guess you have added corner radius in your collection view and set clipsToBounds true. If you don't need rounded collection view then remove cornerRadius and set clipsToBounds false. Or if you need both of them rounded then maintain padding between collection view and button. You can do this by fine-tuning the section inset property.
I had a great 8 hours of sleep and cuz that and Rob's comment, I tried to dig into debug for a bit, and I noticed a warning message which were saying that behaviour of UICollectionViewFlowLayout is not set... (and so on). So I decided to set up UICollectionViewDelegateFlowLayout like this:
extension ProfileTilesTableViewCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top:0, left:10, bottom:0, right: 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (collectionView.frame.width - 40) / 3 , height: collectionView.frame.height - 5)
}
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 10
}
And finally :D somehow it started working properly !
So I deleted everything that I used for testing, deleted testBtn and changed testBtn.roundedCorners to contView.roundedCorners, set back the collectionView properties and it's looking near to what I'm looking for: Screenshot2.png
Thanx for your answers, especially to Rob's one. This is what I was looking for !
Best regards SB !
I have a collectionView who's height and width I set with constraints using autolayout.
In my
func collectionView(_ collectionView: ...., sizeForItemAt indexPath: IndexPath) I return CGSize(width: self.collectionView.frame.width-20, height: self.collectionView.frame.height) and as seen on the image linked below it lines up perfectly fine.
The problem is that the container view (white space) of that cell doesn't fill up the green space (that is the cell's background) at all even though I have set constraints of the containerView to hug left/right/bottom/up with 0 margin.
What I have tried so far:
Make a height constraint for the container view that I assign the collection view's height
updateConstraints() in cellForItemAt and inside the cell's class in ```layoutSubview()````
Set the container view's frame to the collectionView's frame
cell.layoutIfNeeded()in cellForItemAt
None of these have solved my problem.
https://i.stack.imgur.com/mD2iC.jpg
Here issue related to inset I think. Please use collection delegate method
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}
or
UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setSectionInset:UIEdgeInsetsMake(top, left, bottom, right)];
Swift 5.1
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 15.0
}
I'm new to iOS and Swift, I'm trying to create a UICollectionView for the first time.
Something is not quite right when running what I made. Here's what it looks like in my storyboard:
But when I run:
Top grey area became longer than before and bottoms of the cells seem clipped. I just wrote few lines of code to make the cells' height equal to the collection view's.
let height = collectionView.frame.height
cell.frame.size.height = height
return cell
Any suggestions?
Swift 4 code is here
1) Uncheck the Automatic field of the Row Height in the attribute inspector.
2) Then set the delegate funcitons
extension ViewController : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var width = CGFloat(80) //change "80" with your cell width
return CGSize(width: width ,height : self.collectionView.frame.height)
}
}
Please use collectionViewLayout to give a size for an item,
class YourController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
and
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = collectionView.frame.height
let width = UIScreen.main.bounds.width / 3
let size = CGSize(width: width, height: height)
return size
}
You can make changes from storyboard or from code. I have done from storyboard as shown in image.
And also write this method in your view controller to give a size to your item. For that inherit UICollectionViewDelegateFlowLayout method in your view controller.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let size = collectionView.frame.width / 3
return CGSize(width: size - 20, height: size - 20 )
}
Note: This is just an example. You can set your collection view cell frame.
To change height in a collection view, do not change the cell frame height. There is another delegate for the collection view to set cell height and width.
extension ViewControll : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: anyWidth, height: collectionView.frame.size.height)
}
}
Here, anyWidth means whatever width you put. It's up to you
I want to set custom horizontal scroll for my CollectionView, that it will be scrolling by 1 cell (not by the whole width of my screen).
I could set HORIZONTAL scroll, but not custom. (See screens).
1 screen: my extension of my collectionView for UIScrollViewDelegate.
*I saw, that in console (see too) "x" - my offset = 290 - it's true! But on fact it is not 290. Paging was marked in "true" 2 screen: delegate and dataSource.
Help, please!
First you need to set your collectionView scroll direction horizontal (UICollectionViewScrollDirectionHorizontal) and set pagingEnabled to YES
It means your collection view will be scroll horizontally with one by one cell.
Set horizontal direction (Select collection view from XIB or Storyboard)
And for set pagination enable
myCollectionView.pagingEnabled = true
Updated :
You should use of UICollectionViewDelegateFlowLayout delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let width = UIScreen.main.bounds.size.width
var height = 101.7 // set height as you want
return CGSize(width: width, height: height)
}
If using storyBoard the go to collection view and select the right handed tab "show the size inspector" and change
minimum spacing for cells = 0
minimum spacing for lines = 0
if you want to change directly from code then implement these UICollectionViewDelegateFlowLayout methods
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
must be remember scrolling direction set horizontal
and pagination enabled
and implement this delegate methods into code
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath:
IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width, height:
collectionView.frame.size.height)
}
}
You could create a custom UICollectionViewFlowLayout that will center the cells in the screen and then page one at a time. Karmadust have written a good blog post that I have successfully used in the past to do the same thing
http://blog.karmadust.com/centered-paging-with-preview-cells-on-uicollectionview/
By default, a collection view will attempt to space out the cells in the collection by spacing them evenly so that there will be one cell touching either side of the collection view. Example:
But, when the cell is too wide to fit multiple cells in one row on the collection view, it will centre the cell in the collection view.
Is there a way to make the behaviour of centring cells, like in the 3rd picture, the default for the collection view so that there is 0 space between the individual cells and space on either side to the edges of the collection view?
Not that I'm aware of. You should implement something like this:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
CGFloat width = UIScreen.mainScreen().bounds.size.width
return CGSize(width, anyHeight)
}
and then implement the delegate method below as well:
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return UIEdgeInsetsZero
}
Make sure to implement rotation handling too if it's applicable.
My answer would be to use a carefully set up something like
let insets = UIEdgeInsets(top: yourvalues, left: yourvalues, bottom: yourvalues, right: yourvalues),
and feed it to either YourCollectionView.contentInset, or
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return sectionInsets
}
This should work! Lemme know if you have any troubles with it!