Using `sectionHeadersPinToVisibleBounds` while a `UIRefreshControl` is refreshing causes incorrect position of sticky headers - uicollectionview

When using a UICollectionView with a UICollectionViewFlowLayout that has sectionHeadersPinToVisibleBounds set to true the sticky headers will be positioned incorrectly when a UIRefreshControl added to the collection view is refreshing.
Example view controller:
import UIKit
public final class StickyHeaderTestViewController: UICollectionViewController {
init() {
let layout = UICollectionViewFlowLayout()
layout.sectionHeadersPinToVisibleBounds = true
super.init(collectionViewLayout: layout)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override public func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "UICollectionViewCell")
collectionView.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "UICollectionReusableView")
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshControlValueChanged(_:)), for: .valueChanged)
collectionView.refreshControl = refreshControl
}
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: view.bounds.width, height: 40)
layout.headerReferenceSize = CGSize(width: view.bounds.width, height: 40)
}
override public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionViewCell", for: indexPath)
switch indexPath.section {
case 0:
cell.backgroundColor = .blue
case 1:
cell.backgroundColor = .yellow
case 2:
cell.backgroundColor = .blue
default:
break
}
return cell
}
override public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "UICollectionReusableView", for: indexPath)
switch indexPath.section {
case 0:
view.backgroundColor = .brown
case 1:
view.backgroundColor = .green
case 2:
view.backgroundColor = .brown
default:
break
}
return view
}
override public func numberOfSections(in collectionView: UICollectionView) -> Int {
3
}
override public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
10
}
#objc private func refreshControlValueChanged(_ sender: UIRefreshControl) {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
sender.endRefreshing()
}
}
}
Is there a workaround for this issue?

Related

CollectionViewCell not appearing in collectionView

I have an issue where a custom UICollectionViewCell will not appear in the UICollectionView. Anyone know what I am missing? I appreciate it in advance.
Below is my UICollectionViewController:
private let reuseIdentifier = "FeedCell"
class FeedViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
// MARK: Properties
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
self.collectionView!.register(FeedCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
//MARK: - UICollectionViewFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = view.frame.width
return CGSize(width: width, height: width)
}
//MARK: - UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
print("CELL")
cell.backgroundColor = .black
return cell
}
//FEED CELL
class FeedCell: UICollectionViewCell {
//MARK: - Properties
let profileImageView: CustomeImageView = {
let imageView = CustomeImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.backgroundColor = .lightGray
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .red
print("feedcell1")
addSubview(profileImageView)
profileImageView.anchor(top: topAnchor, bottom: nil, left: leftAnchor, right: nil, paddingTop: 8, paddingBottom: 0, paddingLeft: 8, paddingRight: 0, width: 40, height: 40)
profileImageView.layer.cornerRadius = 40/2
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
THANKS :)
The issue was I had previously instantiated FeedViewController with
FeedViewController(collectionViewLayout: UICollectionViewLayout())
instead of `FeedViewController(collectionViewLayout:
UICollectionViewFlowLayout()))` since FeedViewController has
UICollectionViewDelegateFlowLayout protocol.

CABasicAnimation stops when UICollectionView is reloaded

I need help with an issue in Collection Views. In my collectionView I am using UILongPressGestureRecognizer to start CABasicAnimation in the items (images), but when I remove an item and reload the collectionView the CABasicAnimation is interrupeted.
How can I prevent the animation stop?
I need the animation continues until the user decide to stop.
Here is some information about my collectionView:
class SentMemesCollectionVC: UICollectionViewController {
//MARK: - PROPERTIES
var memes: [Meme]! {
return Meme.accessMemes().memes
}
//MARK: - LIFE CYCLE
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap(_:)))
self.collectionView.addGestureRecognizer(longPressGesture)
}
#objc func longTap(_ gesture: UILongPressGestureRecognizer) {
switch gesture.state {
case .began:
print("LongPress begin")
guard let selectedIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {return}
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
setEditing(true, animated: true)
default:
collectionView.cancelInteractiveMovement()
}
}
// MARK: - COLLECTIONVIEW DATA SOURCE
//Defini o número de itens em cada seção
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return memes.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! GridMemeCell
let meme = memes[indexPath.row]
cell.prepareGridCell(with: meme)
cell.delegate = self
return cell
}
// MARK: - COLLECTIONVIEW DELEGATE
/*
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let memeDetail = storyboard?.instantiateViewController(withIdentifier: "DetailVC") as! MemeDetailVC
let meme = memes[indexPath.row]
memeDetail.memeSelected = meme
Feedback.share.hapticFeedback()
navigationController?.pushViewController(memeDetail, animated: true)
}
*/
// MARK: - DELETE ITEMS IN COLLECTVIEW
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
Feedback.share.hapticFeedback()
if let indexPaths = collectionView?.indexPathsForVisibleItems {
for indexPath in indexPaths {
if let cell = collectionView?.cellForItem(at: indexPath) as? GridMemeCell {
if editing {
cell.isEditing = editing
cell.startAnimate()
doneBarButtonItem()
} else {
cell.isEditing = editing
cell.stopAnimate()
addBarButtonItem()
}
}
}
}
}
}
Here is my CollectionViewCell
class GridMemeCell: UICollectionViewCell {
//MARK: - OUTLETS
#IBOutlet weak var ivImage: UIImageView!
#IBOutlet weak var deleteMeme: UIVisualEffectView!
//MARK: - PROPERTIES
weak var delegate: GridMemeCellDelegate?
var isAnimate: Bool! = true
//MARK: - METHODS AND COMPUTED PROPERTIES
func prepareGridCell(with meme: Meme) {
ivImage.image = meme.memeImage
deleteMeme.layer.cornerRadius = deleteMeme.bounds.width / 2.0
deleteMeme.layer.masksToBounds = true
deleteMeme.isHidden = !isEditing
deleteMeme.contentView.backgroundColor = Theme.current.subViewColor
}
func startAnimate() {
let shakeAnimation = CABasicAnimation(keyPath: "transform.rotation")
shakeAnimation.duration = 0.05
shakeAnimation.repeatCount = 4
shakeAnimation.autoreverses = true
shakeAnimation.duration = 0.2
shakeAnimation.repeatCount = 99999
let startAngle: Float = (-2) * 3.14159 / 180
let stopAngle = -startAngle
shakeAnimation.fromValue = NSNumber(value: startAngle)
shakeAnimation.toValue = NSNumber(value: 3 * stopAngle)
shakeAnimation.autoreverses = true
shakeAnimation.timeOffset = 290 * drand48()
let layer: CALayer = self.layer
layer.add(shakeAnimation, forKey: "animate")
self.deleteMeme.isHidden = false
isAnimate = true
}
func stopAnimate() {
let layer: CALayer = self.layer
layer.removeAnimation(forKey: "animate")
self.deleteMeme.isHidden = true
isAnimate = false
}
var isEditing: Bool = false {
didSet {
deleteMeme.isHidden = !isEditing
}
}
#IBAction func btDeleteMeme(_ sender: Any) {
Feedback.share.hapticFeedback()
delegate?.deleteCell(cell: self)
}
}
And here is my Protocol Delegate Cell:
protocol GridMemeCellDelegate: class {
func deleteCell(cell: GridMemeCell)
}
And here is my extension CollectionView - Delegate.
extension SentMemesCollectionVC: GridMemeCellDelegate {
func deleteCell(cell: GridMemeCell) {
if let indexPath = collectionView.indexPath(for: cell) {
//Apaga o Meme do Array
Meme.accessMemes().memes.remove(at: indexPath.item)
collectionView.reloadData()
}
}
}

Select first Item in CollectionView Swift4

I'm trying to select the first Item in CollectionView when the Collectionview loads. I found many solutions for Swift 3 but nothing of that worked for me in Swift4. What I tried(viewDidAppear):
import UIKit
import SDWebImage
class PostsTab_Details: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var PostsSelectRarityCollectionView: UICollectionView!
#IBOutlet weak var RarityTypeLbl: UILabel!
//Center my Collectionview Horizontal
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let totalCellWidth = 100 * (selectedPosts?.rarity.count)!
let totalSpacingWidth = 10 * (3 - 1)
let leftInset = (PostsSelectRarityCollectionView.frame.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (selectedPosts?.rarity.count)!
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = PostsSelectRarityCollectionView.dequeueReusableCell(withReuseIdentifier: "PostssTab_DetailCollectionCell", for: indexPath) as! PostsTab_DetailsCollectionViewCell
cell.PostssTab_DetailCollectionImage.sd_setImage(with: URL(string: (selectedPosts?.PostsImageURL)!))
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
RarityTypeLbl.text = selectedPosts?.rarity[indexPath.row].rarity
}
//Tried this also with IndexPath(item: 0, section: 0)
override func viewDidAppear(_ animated: Bool) {
let selectedIndexPath = IndexPath(row: 0, section: 0)
PostsSelectRarityCollectionView.selectItem(at: selectedIndexPath, animated: true, scrollPosition: .right)
}
var selectedPosts: Posts?
override func viewDidLoad() {
PostsSelectRarityCollectionView.delegate = self
PostsSelectRarityCollectionView.dataSource = self
}
}
But this is not working... I hope someone knows what I'm doing wrong..
Thanks in advance
Update:
This worked for me now, thanks to Razib's answer:
override func viewWillAppear(_ animated: Bool) {
self.collectionView(PostsSelectRarityCollectionView, didSelectItemAt: IndexPath(row: 0, section: 0))
}
Your code seems okay to me. If you like to trigger the didSelectItemAt method, use the following code.
override func viewDidAppear(_ animated: Bool) {
self.PostsSelectRarityCollectionView(self.PostsSelectRarityCollectionView, didSelectItemAt: IndexPath(row: 0, section: 0))
}
To programmatically select the first Item in CollectionViewCell when the Collectionview loads you should code in viewDidAppear:
override func viewDidAppear(_ animated: Bool) {
let indexPath:IndexPath = IndexPath(row: 0, section: 0)
collectionView?.selectItem(at: indexPath, animated: false, scrollPosition: .top)
}
Try this (Swift 5):
let indexPath:IndexPath = IndexPath(row: 0, section: 0)
collectionView?.selectItem(at: indexPath, animated: false, scrollPosition: .top)

Collection view cell not appear after resize the CollectionView height

I am facing the UICollectionView cell size issue. I am using two collection_view and one table_view 1:- Main CollectionView ,which is use for swipe and only display one cell at one time 2:- Inside Main Collection_View, i use table_view and now further inside table_view I am using Collection view which display 6 cell at one time.
Now the whole process is I am using a layout which is swipable and display 6 item at one page and so on.
The problem is when I set main cell height 200 then inside collectionview cell not appearing as expected.
Outer CollectionView Class
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var collectionMain: UICollectionView!
#IBOutlet weak var tableView: UITableView!
let itemsPerRow: CGFloat = 1
let sectionInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController:UICollectionViewDataSource,UICollectionViewDelegate {
//1
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
//2
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return 3
}
//3
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell:cellCollectionCollectionViewCell! = collectionView.dequeueReusableCell(withReuseIdentifier: "cellSwipe",
for: indexPath) as! cellCollectionCollectionViewCell
switch indexPath.item {
case 0:
cell.backgroundColor = UIColor.black
cell.setupCollectionTableCell(indexPath)
break
case 1: cell.backgroundColor = UIColor.red
cell.setupCollectionTableCell(indexPath)
break
default:
cell.backgroundColor = UIColor.yellow
cell.setupCollectionTableCell(indexPath)
break
}
// Configure the cell
return cell
}
}
extension ViewController : UICollectionViewDelegateFlowLayout {
//1
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
//2
let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
let availableWidth = self.collectionMain.frame.width - paddingSpace
let widthPerItem = availableWidth / itemsPerRow
return CGSize(width: widthPerItem, height: widthPerItem)
}
//3
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
// 4
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return sectionInsets.left
}
}
Model Constant class
import UIKit
class Constant {
static let totalItem: CGFloat = 9
static let column: CGFloat = 3
static let minLineSpacing: CGFloat = 1.0
static let minItemSpacing: CGFloat = 1.0
static let offset: CGFloat = 1.0 // TODO: for each side, define its offset
static func getItemWidth(boundWidth: CGFloat) -> CGFloat {
let totalWidth = boundWidth - (offset + offset) - ((column - 1) * minItemSpacing)
return totalWidth / column
}
}
Table Cell Class
import UIKit
class CollectionCell: UITableViewCell {
#IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.sectionInset = UIEdgeInsetsMake(
Constant.offset, // top
Constant.offset, // left
Constant.offset, // bottom
Constant.offset // right
)
layout.minimumInteritemSpacing = Constant.minItemSpacing
layout.minimumLineSpacing = Constant.minLineSpacing
}
collectionView.isScrollEnabled = false
collectionView.dataSource = self
collectionView.delegate = self
}
}
extension CollectionCell: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(Constant.totalItem)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BoxCell", for: indexPath)
return cell
}
}
extension CollectionCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth = Constant.getItemWidth(boundWidth: collectionView.bounds.size.width)
return CGSize(width: itemWidth, height: 50)
}
}
Main CollectionCell class
import UIKit
class cellCollectionCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var tblView: UITableView!
var indexPath:IndexPath?
func setupCollectionTableCell(_ row:IndexPath){
self.indexPath = row
self.tblView.delegate = self
self.tblView.dataSource = self
// self.tblView.estimatedRowHeight = 300
self.tblView.reloadData()
}
}
extension cellCollectionCollectionViewCell:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return 50
case 1:
let itemHeight = Constant.getItemWidth(boundWidth: tableView.bounds.size.width)
let totalRow = ceil(Constant.totalItem / Constant.column)
let totalTopBottomOffset = Constant.offset + Constant.offset
let totalSpacing = CGFloat(totalRow - 1) * Constant.minLineSpacing
let totalHeight = ((itemHeight * CGFloat(totalRow)) + totalTopBottomOffset + totalSpacing)
print("total height \(totalHeight)")
return totalHeight
default:
return UITableViewAutomaticDimension
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// switch indexPath.row {
// case 0:
// let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell", for: indexPath)
// return cell
// default:
// let cell = tableView.dequeueReusableCell(withIdentifier: "CollectionCell", for: indexPath) as! CollectionCell
// return cell
// }
let cell = tableView.dequeueReusableCell(withIdentifier: "CollectionCell", for: indexPath) as! CollectionCell
return cell
}
When I set height of Main Collection view 200
Bellow are the link of images
When I set height 300, working fine

CollectionView does not work when embedded in Navigation Controller

I have a simple collection view test (based on an online tutorial) which works fine stand alone. But when I embed it in a navigation controller it stops working. I built the screen in code by (1) creating a headerView (64 pixel high) and added it to the view at the top. (2) I built a collection view and added it to the headerView.
Here is the code:
import UIKit
class ViewController: UIViewController,
UICollectionViewDelegate, UICollectionViewDataSource,
UINavigationControllerDelegate
{
var collectionView : UICollectionView!
var topView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
var frame = CGRect(x:0,y:128, width:view.frame.width, height:64)
topView = UIView(frame:frame)
self.view.addSubview(topView)
// CollectionView
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
layout.itemSize = CGSize(width: 50, height: 50)
frame = CGRect(x: 0, y: 0, width: Int(self.topView.frame.width), height: Int(self.topView.frame.height))
collectionView = UICollectionView (frame: frame, collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")
collectionView.backgroundColor = UIColor.green
self.topView.addSubview(collectionView)
}
//MARK: - CollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 14
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
for v in cell.subviews {
v.removeFromSuperview()
}
cell.backgroundColor = UIColor.orange
let label = UILabel(frame: CGRect(x:0 , y:0 , width:50 , height:50))
label.text = "\(indexPath.item)"
label.textAlignment = .center
label.textColor = UIColor.white
cell.addSubview(label)
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I couldn't make Kaushal's suggestion work as stated. It did give me a clue that my positioning of the view in which I had embedded the collection view was being misplaced in viewDidLoad for reasons that I have not understood. However by putting the collection view configuration in viewDidAppear (rather than viewDidLoad) it worked well. I offset the y position by 64 to clear the navbar, and I reduced the row height to 64. I also, put code to execute the code only once so that navigating from pages does not add multiple views of top of each other. BTW, my original objective was to have horizontally scrolling cells. In my program I have tableview with corresponding sections and the idea is to use the row with horizontally scrolling cells to move to a corresponding section.
The code is shown below:
//
// CustomViewController.swift
// DSM Tracker
//
// Created by Syed Tariq on 1/7/17.
// Copyright © 2017 com.syedtariq. All rights reserved.
//
import UIKit
class ViewController: UIViewController,
UICollectionViewDelegate,
UICollectionViewDataSource,
UINavigationControllerDelegate
{
var executeOnce = true
var cellDimensions = [String:Int]()
var cellHeight = 50
var cellWidth = 120
var collectionContainerView: UICollectionView!
var navBar: UINavigationBar = UINavigationBar()
// view constants
var viewY = CGFloat()
var viewX = CGFloat()
var viewWidth = CGFloat()
var viewHeight = CGFloat()
// gaps from view edge
let leftGap = CGFloat(20)
let rightGap = CGFloat(20)
// navbar constants
let navBarHeight = CGFloat(64)
var headerLabels = ["Cell 01","Cell 02","Cell 03","Cell 04","Cell 05","Cell 06","Cell 07","Cell 08","Cell 09","Cell 10","Cell 11","Cell 12","Cell 13","Cell 14","Cell 15","Cell 16"]
override func viewDidLoad() {
super.viewDidLoad()
navBar.backgroundColor = UIColor.green
executeOnce = true
viewY = view.frame.origin.y
viewX = view.frame.origin.x
viewWidth = view.frame.width
viewHeight = view.frame.height
}
func configureCollectionView () {
if executeOnce {
executeOnce = false
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
layout.itemSize = CGSize(width: cellWidth, height: cellHeight)
let colWidth = viewWidth - leftGap - rightGap
let colX = viewX + leftGap
let colY = viewY + navBarHeight
let colHeight = CGFloat(64)
let frame = CGRect(x:colX, y:colY, width: colWidth, height: colHeight)
//let frame = CGRect.zero
collectionContainerView = UICollectionView (frame: frame, collectionViewLayout: layout)
collectionContainerView.dataSource = self
collectionContainerView.delegate = self
collectionContainerView.autoresizingMask = [.flexibleLeftMargin,.flexibleLeftMargin,.flexibleBottomMargin,.flexibleRightMargin, .flexibleHeight, .flexibleWidth]
collectionContainerView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")
collectionContainerView.backgroundColor = UIColor.blue
collectionContainerView.allowsSelection = true
collectionContainerView.isScrollEnabled = true
collectionContainerView.setNeedsDisplay()
print("collectionContainerView.frame \(collectionContainerView.frame)")
view.addSubview(collectionContainerView)
}
}
override func viewDidAppear(_ animated: Bool) {
configureCollectionView()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("headerLabels.count \(headerLabels.count)")
return headerLabels.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
for v in cell.subviews {
v.removeFromSuperview()
}
let cellTitle = headerLabels[indexPath.row]
let cellTitleLines = cellTitle.components(separatedBy: " ")
let nLabels = cellTitleLines.count
cell.layer.borderWidth = 1
cell.layer.cornerRadius = 8
let labelHeight = cellHeight / cellTitleLines.count
for i in (0 ..< nLabels) {
let frame = CGRect(x: 0, y: labelHeight * i, width: cellWidth, height: labelHeight)
let label1 = UILabel(frame: frame)
cell.backgroundColor = UIColor.lightGray
label1.numberOfLines = 1
label1.text = headerLabels[indexPath.row]
label1.textAlignment = .center
label1.textColor = UIColor.black
label1.clipsToBounds = true
label1.adjustsFontSizeToFitWidth = true
label1.text = cellTitleLines[i]
cell.addSubview(label1)
}
return cell
}
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
collectionContainerView.scrollToItem(at:IndexPath(item: indexPath.item, section: 0), at: .centeredHorizontally, animated: false)
return true
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionContainerView.cellForItem(at: indexPath)
print("cell = \(cell)")
collectionContainerView.scrollToItem(at:IndexPath(item: indexPath.item, section: 0), at: .centeredHorizontally, animated: false)
}
func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
}