I have a horizontal collection view in my project which has 2 elements - a button and a label. Button and label are stuck to each other and then I want to show other button and label within the cell with space between 2 elements i.e. Button 1 and label 1, then some space and then display button 2 and label 2. Want to have some space between label 1 and button 2.
I came across some 'UICollectionViewFlowLayout' related methods and did try adding the code for it to test, but the functions are not getting called. Below are the functions:
extension MyController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 50
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 100
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 100, bottom: 100, right: 100)
}
}
However adding 'UICollectionViewFlowLayout' is giving me "Inheritance from non-protocol type 'UICollectionViewFlowLayout'" error.
How can I get 'minimumLineSpacingForSectionAt' and other methods executed? Or how can I add space between label 1 and button 2, and then space between label 2 and button 3?
It is UICollectionViewDelegateFlowLayout
Related
I have a collection view with direction set to horizontal and paging enable. The things is, the height of my collection cell each page sometimes is higher than the phone screen size. What I want to achieve is user can scroll down the cell and swipe right to the next page.
Currently, I only able to display the collection cell one full page, without manage to scroll downward based on content height. Here some code:
extension EventListDetailsVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cat = dataArray[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "celldetails", for: indexPath) as? EventListDetailsCVC
cell?.imageEvent.image = UIImage(named: cat.imageEvent)
cell?.eventTitleLabel.text = cat.titleEvent
cell?.eventDescriptionLabel.text = cat.content
return cell!
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.collectionView.frame.size.width, height: self.collectionView.frame.size.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets.zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
this how it should be
I tried to embed my collectionView into tableView, but it seems does not work because I have dynamic height in a cell.
Is it another way to achive this?
p/s I just started learning swift, thanks.
Have you tried embedding a scroll view inside each collection view cell?
That would make sure that the collection view cell height never exceeds the phone height while the scroll view will work on displaying more content as you scroll down whether it be text or images or whatever view you decide to embed in the scroll view itself.
I think you should try UIPageViewController with the scroll transition style. It has native pagination between pages.
Every page should have UIScrollView.
I am trying to set my collection view cell sizes so that I get two cells per row.
I have looked at plenty of solution for sizing cells for collection views. I actually have used some solutions before for sizing three cells per row that have worked for me.
What I have so far:
extension BusinessViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (view.frame.width - 20) / 2.0
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 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
}
}
Right now I just get one big cell per row and I don't know why. Usually when I have to have 3 cells per row, simply subtracting the insets from the views width and dividing by the number of desired cells is enough. Not sure why this is causing me an issue.
You can try checking the "estimatesSize" property of UICollectionView.
It could have been set to "Automatic" instead of "None".
I solved the same problem with this solution
I created UIImageView inside CollectionViewCell. I wanted for the layout to have the same spacing between the left most cell to left edge as spacing between inner cell, and same spacing for right most cell to the right edge of the screen. The current layout I have is like this:
In the image above the left edge to left most cell has 10 points spacing while the inner cells spacing is twice of that. That is because I have the UIImageView with 10points smaller in all 4 directions (up,down,left,right) against the CollectionViewCell.
I have spend significant time on this issue including searching StackOverflow but can't seems to find the answer.
I have no issue to create N number of cells in a row as per this posting and I've also played with the cell spacing as per this posting
I managed to find the solution to the above problem.
I did the following:
Remove all inner spacing between UIImageView and the CollectionViewCell. Then remove any offset and make the size match. Put constraint of 0 on all 4 directions.
Use the second reference mentioned above as template. I updated my ViewController with following contents:
extension ToDoCategoryViewController: UICollectionViewDelegateFlowLayout {
fileprivate var sectionInsets: UIEdgeInsets {
return UIEdgeInsetsMake(0, Constant.hardCodedPadding, 0, Constant.hardCodedPadding)
}
fileprivate var innerSpacing: CGFloat { return Constant.hardCodedPadding }
fileprivate var rowSpacing: CGFloat { return Constant.hardCodedPadding }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var itemPerRow: CGFloat {
switch collectionView.bounds.width {
case 300..<500:
return 3
case 500..<800:
return 4
default:
return 5
}
}
let innerSpacingCount = itemPerRow - 1
let edgesPadding = Constant.hardCodedPadding * 2.0
let itemWidth = (collectionView.bounds.width - (innerSpacing * innerSpacingCount + edgesPadding)) / itemPerRow
let itemHeight = itemWidth * CGFloat(1.25)
return CGSize(width: itemWidth, height: itemHeight)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return rowSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return innerSpacing
}
}
In my code elsewhere, I set the Constant.hardcodedPadding value, e.g. CGFloat(30.0)
Thus, I get the following view:
I have a UICollectionView with two section. In first, it has UIPageControl and in second simple UICollectionView.
Between first and second element it has spacing, can you suggest me how to remove that?
Platform iOS 9.*, Swift 3
You can specify the UIEdgeInsets of the collection view to solve this problem
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0, 0, 0, 0)
}
I have a one section header and one UITextView in there, constraints 0 to all sides as Superview. Also I have a flow layout. I want to resize my header size after I filled my header reusable view using viewForSupplementaryElementOfKind.
How Can I reach my UITextView() in 0 section header. And than calculate my textView height to return exact value in this function.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: 200.0)
}
If someone explain this case, It would be great.
I was having a similar issue and finally tracked this down:
Make a UICollectionViewDelegateFlowLayout and then implement collectionView(_:layout:referenceSizeForHeaderInSection:)
So for example:
class ViewController: UIViewController,UICollectionViewDelegateFlowLayout {
...
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
if section == 0 {
return CGSize.zero
}else{
//...
}
return CGSize(width: collectionView.frame.width, height: 60)
}