I'm developing an app that show photos for users. My design was like Pinterest app. I added UICollectionView
inside UIScrollView
and disabled UICollectionView
's scroll. But when I use this components like this UICollectionView not scrollable acording to its content. Only visible are showing and other are is not showing. The main pain in this project is CollectionViews' contents are dynamic. It could change with user interacyion. And my question is how to fully scroll UICollectionView with its dynamic content using with UIScrollView.
Let me share screenshots.
First image describes first open. Second image describes scrolling issue. Third image describes my storyboard.
Thanks for helpings.
Here is my storyBoard
And my code
//
// ViewController.swift
// ScrollCollectionView
//
// Created by Cbs on 31.05.2017.
// Copyright © 2017 Cbs. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 25
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.addShadow(opacitiy: 1, shadowRadius: 3, shadowOffsetWidth: 2, shadowOffsetHeight: 2, shadowColor: UIColor.lightGray, backgroundColor: UIColor.red)
cell.addCornerRadius(cornerRadius: 8)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellSpacing = CGFloat(2) //Define the space between each cell
let leftRightMargin = CGFloat(40) //If defined in Interface Builder for "Section Insets"
let numColumns = CGFloat(2) //The total number of columns you want
let totalCellSpace = cellSpacing * (numColumns - 1)
let screenWidth = UIScreen.main.bounds.width
let width = (screenWidth - leftRightMargin - totalCellSpace) / numColumns
let height = CGFloat(210) //whatever height you want
return CGSize(width: width, height: height) // width & height are the same to make a square cell
}
}
EDIT:
I think I couldn't clearly explain my issue. here I'll provide some additional videos to be clearly tell about the issue. I've upload 2 videos.
In this video my header is not scrolling with collectionview childs. So I want to scroll whole elements in screen. (https://youtu.be/0ArQe6mZytc)
In this short video you can see Pinterest App behaviour when scroll. I would like to make my app like this video (https://youtu.be/Nm-sjXVEL5s)
For your requirement, there is no need to use UIScrollView
. You can create the screen just using a UICollectionView
.
To show a scrollable header
, you can use UICollectionReusableView
as the section header
of the collection view
.
1.UICollection view code:
import UIKit
class PinterestViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
}
}
extension PinterestViewController : UICollectionViewDataSource, UICollectionViewDelegate
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 25
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
{
if kind == UICollectionElementKindSectionHeader
{
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerView", for: indexPath)
return headerView
}
return UICollectionReusableView()
}
}
extension PinterestViewController : UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let cellSpacing = CGFloat(2) //Define the space between each cell
let leftRightMargin = CGFloat(40) //If defined in Interface Builder for "Section Insets"
let numColumns = CGFloat(2) //The total number of columns you want
let totalCellSpace = cellSpacing * (numColumns - 1)
let screenWidth = UIScreen.main.bounds.width
let width = (screenWidth - leftRightMargin - totalCellSpace) / numColumns
let height = CGFloat(210) //whatever height you want
return CGSize(width: width, height: height) // width & height are the same to make a square cell
}
}
2. Interface:
3. Output screen:
Edit:
In the code provided in : https://www.raywenderlich.com/107439/uicollectionview-custom-layout-tutorial-pinterest
Make some changes:
class PinterestLayout: UICollectionViewFlowLayout
{
//...
override func prepare()
{
// 1
if cache.isEmpty
{
//...
var yOffset = [CGFloat](repeating: 150, count: numberOfColumns) //Height of your header view
//...
}
}
override var collectionViewContentSize: CGSize
{
return CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
{
guard let attributes = super.layoutAttributesForElements(in: rect) else
{
return nil
}
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attr in attributes where attr.representedElementKind == UICollectionElementKindSectionHeader
{
if let supplementaryAttributes = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: attr.indexPath)
{
layoutAttributes.append(supplementaryAttributes)
}
}
for attributes in cache
{
if attributes.frame.intersects(rect)
{
layoutAttributes.append(attributes)
}
}
return layoutAttributes
}
override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
{
if elementKind == UICollectionElementKindSectionHeader
{
let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, with: indexPath)
attributes.frame = CGRect(x: 0, y: 0, width: self.contentWidth, height: 150) //Height of your header view
return attributes
}
return nil
}
}
Also in Collection View Interface
:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With