How can I design a header view for my UICollectionView that either grows or shrinks its height based on the content of it? It contains some labels, but the text of the labels are not known in advance.
If your layout is an UICollectionViewFlowLayout (or based on it) you can implement the
optional func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
referenceSizeForHeaderInSection section: Int) -> CGSize
function on you view controller and return the header size you want.
See here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewDelegateFlowLayout_protocol/#//apple_ref/occ/intfm/UICollectionViewDelegateFlowLayout/collectionView:layout:referenceSizeForHeaderInSection:
Related
I am using collection view in my project.
there is always a tap padding comes between collection view and collection view cell.
I want to set the space between collection view cell and its collection view container.
How can I do this ?
Look at the UICollectionViewDelegateFlowLayout : https://developer.apple.com/documentation/uikit/uicollectionviewdelegateflowlayout
You can use this method to tell the collection view how much space you want between rows/columns:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
Read about the method here: https://developer.apple.com/documentation/uikit/uicollectionviewdelegateflowlayout/1617705-collectionview
Make sure you have your collectionView delegate set.
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/
I have a UICollectionView, which uses UICollectionViewFlowLayout to arrange my cells inside the collection view.
Inside my cells, I have an image and a label. Using the above layout I am able to design my collection view with vertical scrolling,
But instead of vertical scrolling, I want a structure like UIPageViewController which will contain my UICollectionView with the above cells.
I have tried with flowLayout.scrollDirection = .horizontal,
But with that approach I could not solve my issue.
I am new to Swift and I am not using storyboards.
Open your storyboard, select the collectionView and change the scroll direction from vertical to horizontal as shown below :)
Now your collectionView will start scrolling horizontally than vertically :)
If you want pagination, like ViewControllers in pageViewController, select the collectionView and select paging enabled check box :)
Now if you want your collection view cell to cover the whole collectionView like view controllers in UIPageViewController, type this in your UICollectionView delegate :)
extension YourViewController : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return self.pageViewController.frame.size
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
}
Want to leave spacing between cells return value instead of 0.0 in the above method :) Thats all
EDIT
In case you dont have storyboard you can set the scroll direction and other properties programmatically using
(self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout).scrollDirection = .horizontal
I found my answer from the below link:
http://swiftiostutorials.com/ios-tutorial-using-uipageviewcontroller-create-content-slider-objective-cswift/
It really helped me a lot. Thanks.
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!
I'm designing the UI of an ios 8 app being built in swift. I have intermediate knowledge of autolayout and constraints. Here's my situation: I have a custom collection view controller and collection view cell. I want to use the "equal widths" and "equal heights" constraints within interface builder to set the width and height of a cell relative to a multiplier of the parent view-- as opposed to using intrinsic height/width properties such as 320 x 94.
Here's what I tried
using intrinsic width and height for size classes within IB. (This doesn't work)
Control-Dragging from a UICollectionViewCell to the CollectionView (didn't work seeing as "equal heights " and "equal widths" are not even constraint options)
Should I just settle for the intrinsic height and width and assume that CollectionViewFlowLayout will take care of me or is there a way to do this programatically?
Thanks.
Alex
Use the UICollectionViewDelegateFlowLayout methods to tune your cell size
for example if you want 3 cells across the view width
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
let width = CGRectGetWidth(collectionView.bounds)
let hcount = 3
let gapcount = CGFloat(hcount) + 1
//this should be a class var/constant which you can feed into the minimumLineSpacingForSectionAtIndex delegate
let gap = 10
let kwidth = width - gap
let keywidth = kwidth/CGFloat(hcount)
return CGSize(width:keywidth,height:50)
}
You can tune the distance between the cells with
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
and the edge insets with
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
Layout and size of cells is done by the collectionViewLayout property of collectionView. Using a collectionViewLayout of class UICollectionViewFlowLayout, you can set fixed size using item size property:
(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.itemSize = 100 //set fixed size here
or set variable size using delegate method:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// determine variable size here using indexPath value
}