Place the collection view cells vertically instead of horizontally? - ios

How to design UICollectionView in such a way that it fills the collection view cells vertically (column-wise) instead of filling horizontally (row-wise)?
The collection view should be vertically scrollable, I should not change the size of the collection cell and determine the number of rows dynamically?

(YOUR_COLLECTIONVIEW_NAME.collectionViewLayout as? UICollectionViewFlowLayout).scrollDirection = .horizontal

I use this code for it:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
myCollectionView.collectionViewLayout = layout
For limited number of rows you can set collectionView height and set height of cell and spacings. For example, if you need 2 cells in column, you will write:
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: self.collectionView.frame.size.width / 5, height: self.collectionView.frame.size.height / 2.5)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
you can change this parameters like you need

Related

UICollection spacing not working I Don't wont any spacing in uicollectionview

I have tried following but not working
self.hCltVw.constant = (rowHeight * 8.0)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: size, height:rowHeight)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView.reloadData()
collectionView.collectionViewLayout = layout
But still spaing in collectionview row. Dont know why spacing is not working also if i add + 80 in collectionview height spacing is automatically removed.
My Xib Setup
NOTE: the strange thing is if I increase collection-view height
constant then space is decreasing.
i had same problem, i solved it by this may be it will helpful for you .
in storybord select your collectionview and change some settings in attribute inspector.
set estimate size = none
in section insets top,bottom,left,right set this all value 0
set min Spacing (for cell , for line both) = 0
[edited]
try this:-
let width = (view.frame.size.width) / 3
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width)

How to reduce space between 2 message cell in MessageKit Library Swift?

I'm using MessageKit Chat Library. I removed the Avatar View from message cell. But the space between 2 message cells is too much. I want to reduce space between 2 message cell. how can I do that ?
Edit:
I solved problem with cell spacing on cell in CollectionView
if let layout = messagesCollectionView.collectionViewLayout as? MessagesCollectionViewFlowLayout {
layout.textMessageSizeCalculator.outgoingAvatarSize = .zero
layout.textMessageSizeCalculator.incomingAvatarSize = .zero
layout.sectionInset = UIEdgeInsets(top: -10, left: 0, bottom: -5, right: 0)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
}

UICollectionviewCell always placing at the edge of the view

my UICollectionViewCells are always placing at the edges of the UICollectionView. There is a middle space always like this.
What is the reason for that? And I want to keep 3 items per row always. But in this way it just set 2. How to fix this issue?
Please help me.
Thanks
UPDATE
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical //.horizontal
layout.itemSize = cellSize
layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
layout.minimumLineSpacing = 1.0
layout.minimumInteritemSpacing = 1.0
layout.minimumLineSpacing=1.0
btncollectionView.setCollectionViewLayout(layout, animated: true)
btncollectionView.reloadData()
Works for both horizontal and vertical scroll directions, and variable spacing
Declare number of cells you want per row
let numberOfCellsPerRow: CGFloat = 3
Configure flowLayout to render specified numberOfCellsPerRow
if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
let horizontalSpacing = flowLayout.scrollDirection == .vertical ? flowLayout.minimumInteritemSpacing : flowLayout.minimumLineSpacing
let cellWidth = (view.frame.width - max(0, numberOfCellsPerRow - 1)*horizontalSpacing)/numberOfCellsPerRow
flowLayout.itemSize = CGSize(width: cellWidth, height: cellWidth)
}

UICollectionView horizontal paging with space between pages

I'm looking for a way to replace the native UIPageViewController horizontal paging with a UICollectionView.
so far i did the following:
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = collectionView.frame.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 10
collectionView.setCollectionViewLayout(layout, animated: false)
collectionView.isPagingEnabled = true
collectionView.alwaysBounceVertical = false
this works fine and i get an horizontal paging effect.
Now i want to add horizontal space between the pages (like u will do with UIPageViewControllerOptionInterPageSpacingKey on UIPageViewController)
so far i couldn't fine a way to add the spaces without damaging the paging effect.
im looking for the same behavior as with the UIPageViewController: the cell should fill the entire screen width, and the space between the cells should only be visible when switching a page.
Solution one:
collectionView.isPagingEnabled = false
add a minimumLineSpacing for the distance between pages
implement targetContentOffsetForProposedContentOffset:withScrollingVelocity: to move the contentOffset to the closest page. You can calculate the page with simple math based on your itemSize and minimumLineSpacing, but it can take a little work to get it right.
Solution Two:
collectionView.isPagingEnabled = true
add a minimumLineSpacing for the distance between pages
the paging size is based on the bounds of the collectionView. So make the collectionView larger then then screenSize. For example, if you have a minimumLineSpacing of 10 then set the frame of the collectionView to be {0,-5, width+10, height}
set a contentInset equal to the minimumLineSpacing to make the first and last item appear correctly.
By default, UICollectionViewFlowLayout's minimumLineSpacing is 10.0, when collectionView's item is horizontally filled (itemSize.width = collectionView.bounds.width) and collectionView is paging enabled, greater than zero 'minimumLineSpacing' will cause an unintended performance: start from second page, every page has a gap which will be accumulated by page number.
It seems that we can expand collectionView's width by 'minimumLineSpacing' to fix this problem. But pratice negates this solution: When there are tow pages or more, collectionView will not give the last one a 'lineSpacing', so it's 'contentSize' is not enough to show this page's content completely, which means if the 'minimumLineSpacing' were 10.0, the last page's end would overstep the collectionView's contentSize by 10.0.
Finally, I use the following simple solution to insert a margin between every item (like UIScrollView's preformance): Expand every collectionViewItem's width by a fixed value 'pageSpacing' (such as 10.0), and expand the collectionView's width by the same value, too. And don't forget that, when layout collevtionViewCell's subviews, there's an additional spacing which is not for diplaying the real content.
Heres the code written in Swift 3.1, I'm sure it's easily understanding for you:
let pageSpacing: CGFloat = 10
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: view.frame.width + pageSpacing, height: view.frame.height)
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
let frame = CGRect(x: 0, y: 0, width: view.frame.width + pageSpacing, height: view.frame.height)
let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
view.addSubview(collectionView)
}
}
class MyCell: UICollectionViewCell {
var fullScreenImageView = UIImageView()
override func layoutSubviews() {
super.layoutSubviews()
fullScreenImageView.frame = CGRect(x: 0, y: 0, width: frame.width - pageSpacing, height: frame.height)
}
}
Hope that can help you.

UICollectionView layout change when frame size changes

I'm working with a UICollectionView but I have a weird behaviour.
I want a horizontal scroll, small cell height ( smaller than the UICollectionView height).
Tapping a button will increase even more the height of the collection.
The problem is that the layout of my cells is changing also.
I want the collection view height to increase with the cells staying in the same position.
Here attached 2 screen captures (before/after button touched).
Here is my code:
var smallLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout();
smallLayout.scrollDirection = .Horizontal
var itemHeight = 100
smallLayout.itemSize = CGSizeMake(150, itemHeight);
var bottomDist:CGFloat = 1
var topDist = collHeight - itemHeight - bottomDist
smallLayout.sectionInset = UIEdgeInsets(top: topDist, left: 2, bottom: bottomDist, right: 2)
smallLayout.minimumInteritemSpacing = 15
smallLayout.minimumLineSpacing = 10
So, when touching the button I have the following code:
let viewHeight = CGRectGetHeight(self.view.frame)
let viewWidth = CGRectGetWidth(self.view.frame)
var collHeight:CGFloat = 600
var collYPosition = viewHeight-CGFloat(collHeight)-20
var rect = CGRectMake(0, CGFloat(collYPosition), CGFloat(viewWidth), CGFloat(collHeight))
dishCollectionView.frame = rect
So, I cannot understand why my layout is changing.
I want to have my cell at the bottom.
Perhaps if you reset the top of your sectionInset to accommodate for the additional height, i.e. an updated topDist calculation. Try adding something like this to you on touch code:
var bottomDist:CGFloat = 1
var topDist = collHeight - itemHeight - bottomDist
dishCollectionView.collectionViewLayout.sectionInset = UIEdgeInsets(top: topDist, left: 2, bottom: bottomDist, right: 2)
dishCollectionView.collectionViewLayout.invalidateLayout()

Resources