Connecting Custom layout class to collection view in code

Connecting Custom layout class to collection view in code



i have a small question about a custom layout class and i need to connect it to my collection view in code not by the story board because i create the whole project by code . any help, please ?



my main class


import UIKit
import Firebase
class UserProfileController: UICollectionViewController
override func viewDidLoad()
super.viewDidLoad()
collectionView?.backgroundColor = .white
//fetchUser()
collectionView?.dataSource = self
collectionView?.delegate = self
collectionView?.register(TestCell.self, forCellWithReuseIdentifier: mainCellId)



fileprivate let mainCellId = "mainCellId"
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: mainCellId, for: indexPath) as! TestCell

return cell


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 15

override func numberOfSections(in collectionView: UICollectionView) -> Int
return 1




the custom layout class which need to connect it to the collection view in code not story board


import UIKit

struct UltraVisualLayoutConstants
struct Cell
static let standardHeight: CGFloat = 100
static let featuredHeight: CGFloat = 280
// static let standardWidth: CGFloat = 100
// static let featuredWidth: CGFloat = 280



class UltraVisualLayout: UICollectionViewLayout {
// amount which users need to scroll before featured cell changes
let dragOffset: CGFloat = 180.0
var cache = [UICollectionViewLayoutAttributes]()
//return item index of current featured cell
var featuredItemIndex: Int
get
//use max to ensure that featureditemindex never be < 0
return max(0 , Int(collectionView!.contentOffset.y / dragOffset))



// returns value between 0 and 1 to represent how close the next cell becomes the featured cell
var nextItemPercentegeOffset: CGFloat
get
return (collectionView!.contentOffset.y / dragOffset) - CGFloat(featuredItemIndex)


// return the width of collection view
var width: CGFloat
get

guard let width = collectionView?.bounds.width else return 0
return width


// return the height of collection view
var height: CGFloat
get
guard let height = collectionView?.bounds.height else return 0
return height


//returns the number of items in the collection view
var numberOfItems: Int
get
return collectionView!.numberOfItems(inSection: 0)



// MARK: UICollectionViewLayout
// return the size of all content in collection view
override var collectionViewContentSize: CGSize
let contentHeight = (CGFloat(numberOfItems) * dragOffset) + (height - dragOffset)
return CGSize(width: width, height: contentHeight)

override func prepare()
cache.removeAll(keepingCapacity: false)

let standardHeight = UltraVisualLayoutConstants.Cell.standardHeight
let featuredHeight = UltraVisualLayoutConstants.Cell.featuredHeight
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
var y: CGFloat = 0
for item in 0..<numberOfItems
let indexPath = NSIndexPath(item: item, section: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath)
attributes.zIndex = item
var height = standardHeight
if indexPath.item == featuredItemIndex
let yOffset = standardHeight * nextItemPercentegeOffset
y = collectionView!.contentOffset.y - yOffset
height = featuredHeight
else if indexPath.item == (featuredItemIndex + 1) && indexPath.item != numberOfItems
let maxY = y + standardHeight
height = standardHeight + max((featuredHeight - standardHeight) * nextItemPercentegeOffset, 0)
y = maxY - height

frame = CGRect(x: 0, y: y, width: width, height: height)
attributes.frame = frame
cache.append(attributes)
y = frame.maxY




// return all attributes in cache whose frame intersects with the rect passed to the method
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attributes in cache
if attributes.frame.intersects(rect)
layoutAttributes.append(attributes)


return layoutAttributes


// return true so that layout is continuously invalidated as the user scrolls
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool
return true





Hello and welcome to Stackoverflow. Could you kindly post your code as text rather than an image so it is easier to read.
– Chris Edgington
Aug 23 at 15:23





sry for that , i edited it @Chris Edgington
– Ahmed Seddek
Aug 23 at 15:38





1 Answer
1



You cannot set the layout programmatically if you don't have an initializer. From the docs:



layout



The layout object to use for organizing items. The collection
view stores a strong reference to the specified object. Must not be
nil
.



Since you seem to be using the storyboard, you'll have to set it there.



enter image description here



Once you create you layout class in code, it will show up when you click you collection view on the storyboard. The default layout will be set to Flow, when you change it to Custom, a new class field will show up. When you click that, it will list your layout class. You can choose it and set it from there.



However if you are initializing your storyboard programmatically, then you just need to pass it as a parameter to your initializer.


var collectionView = UICollectionView(frame: yourFrame, collectionViewLayout: customCollectionViewLayout) // pass your custom collection view instance





thanks for replying . how can i use the initializer in the right way ? that is what i want . i know the way to connect it in story board but i can't connect it in code in the main class if that possible . i don't use story board
– Ahmed Seddek
Aug 23 at 15:57






@AhmedSeddek if you don't use storyboard, why is your collectionView an optional?
– Rakesha Shastri
Aug 23 at 16:00


collectionView





i don't know , when i create it , xcode put optional front of it after adding delegate or data source or register the cell . am trying new animation through custom layout and i found the custom layout class in tutorial but it uses the same way u said by connecting it through story board not code :/
– Ahmed Seddek
Aug 23 at 16:11





@AhmedSeddek please show the code (edit it to the question) where you initialize the UICollectionView.
– Rakesha Shastri
Aug 23 at 16:12






this is the full code of my code and this is my TestCell class import UIKit class TestCell: BaseCell override func setupUI() backgroundColor = .purple
– Ahmed Seddek
Aug 23 at 16:14






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)