page control not working for UICollectionView inside UITableView - swift

Im having issue with making page control work for a collection view which is inside table view. There are actually 2 collection views in the view controller, one is outside the tableView and other one is inside. I want page control for inside one. Let me share code below and then explain what is causing trouble:
class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
//setup stories collection view
let nib = UINib(nibName: "StoryCollectionViewCell", bundle: nil)
cvStories.register(nib, forCellWithReuseIdentifier: "StoryCollectionViewCell")
let layout1 = UICollectionViewFlowLayout()
layout1.scrollDirection = .horizontal
layout1.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
collectionViewStories.setCollectionViewLayout(layout1, animated: true)
collectionViewStories.delegate = self
collectionViewStories.dataSource = self
tblHome.dataSource = self
tblHome.delegate = self
}
// MARK: - Table View
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblHome.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
cell.collectionViewPostImages.dataSource = self
cell.collectionViewPostImages.delegate = self
cell.collectionViewPostImages.tag = indexPath.row
cell.collectionViewPostImages.reloadData()
cell.pageControl.hidesForSinglePage = true
cell.pageControl.numberOfPages = self.posts[cell.collectionViewPostImages.tag].imagesArray?.count ?? 0
return cell
}
//MARK: - Collection View
func numberOfSections(in collectionView: UICollectionView) -> Int {
if collectionView == cvStories {
return 2
}
else {
return 1
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == collectionViewStories {
return stories.count
}
else {
return posts[collectionView.tag].imagesArray?.count ?? 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == collectionViewStories {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoryCollectionViewCell", for: indexPath) as! StoryCollectionViewCell
//code to show stories
return cell
}
else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
//code to show images
return cell
}
}
}
//TableViewCell Class
class HomeTableViewCell: UITableViewCell {
#IBOutlet weak var collectionViewPostImages: UICollectionView!
#IBOutlet weak var pageControl: UIPageControl!
var currentPage = 0
override func awakeFromNib() {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: cvPostImages.frame.size.height)
flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
collectionViewPostImages?.collectionViewLayout = flowLayout
collectionViewPostImages.showsHorizontalScrollIndicator = false
collectionViewPostImages.isPagingEnabled = true
}
//ScrollView delegate method
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth = scrollView.frame.width
self.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
self.pageControl.currentPage = self.currentPage
}
}
The whole code is like Instagram app, stories at top and posts with images in tableView. Whole code is in single View controller and everything works fine. Even dots (page number) are correct according to number of pages however when you swipe between them they do not change. I saw many solutions and in those pageControl.numberOfPages was used in cellForItemAt function but its out of scope for me so I just called it as cell.pageControl.numberOfPages in cellForRowAt instead. First time dealing with collectionView inside tableView so getting confused getting it worked.

The main problem is you use cell.collectionViewPostImages.delegate = self in HomeViewController but your method scrollViewDidScroll in cell HomeTableViewCell.
Collectionview's own scrollview delegate methods triggering in UICollectionViewDelegate. Thats why scrollViewDidScroll is not triggered in your cell.
Solution is using scrollViewDidScroll in where you delegete the collectionview. It is HomeViewController
By the way, I dont recommend to use cell.collectionViewPostImages.dataSource = self cell.collectionViewPostImages.delegate = self in reusable cell. You dont want to make ...delegate = self on everytime when cell reused. You can take it in awakeFromNib in cell class

Related

How can l put TableView inside CollectionViewCell?

I have a tableView with several cells (created by MVVM-architecture).
In ViewController I fill my tableView like this:
tbv.registerCells(
withModels:
FirstViewModel.self,
SecondViewModel.self,
ThirdViewModel.self)
My task is to put my TableView in one cell of CollectionView. I thought l have to create CollectionView in my ViewController, after it create CollectionViewCell and CollectionCellViewModel, but how to do it exactly I don't understand.
If you know, how to make it, help.
How I have several tableviews in collection views in one of my apps. First I have a view controller in which I build my collection view. As usually proposed in the new design guidelines, I have the Collection View delegate and data source in an extension of this view controller.
In your view controller you define a delegate and data source for your table view. Preferably, this is a different class. I would not have the tableview data source and delegate also in the same view controller as your collection view.
class WorkoutSettingsViewController: UIViewController, LoadWorkoutSettings {
//MARK: - Properties
//Used variables
//Used constants
private let settingsDelegate = SettingsTableViewDelegate()
The extension would then look like this.
extension WorkoutSettingsViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
//Whatever sets your sections
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//Whatever sets your rows per section
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Workout Settings", for: indexPath) as! SettingsCollectionViewCell
settingsDelegate.workoutTitleLabel = [countdown, mainView, spokenMessage]
settingsDelegate.mainContentLabel = getSettingsContent()
cell.settingsTableView.delegate = settingsDelegate
cell.settingsTableView.dataSource = settingsDelegate
cell.settingsTableView.reloadData()
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
//Whatever you need as header or footer
}
The delegate does exactly what you would like the table view data source and delegate to do.
class SettingsTableViewDelegate: NSObject, UITableViewDataSource, UITableViewDelegate {
//MARK: - Properties
//Used variables
var workoutTitleLabel = [String]()
var mainContentLabel = [String]()
var selectedSetting: ((Int) -> ())? = .none
private var secondaryContentLabel = [String]()
//Used constants
private let onTitle = NSLocalizedString("ON", comment: "Localized on title")
private let offTitle = NSLocalizedString("OFF", comment: "Localized off title")
private let fontColorBlack = UIColor(red: 20.0/255.0, green: 20.0/255.0, blue: 19.0/255.0, alpha: 1.0)
private let fontColorRed = UIColor(red: 255.0/255.0, green: 96.0/255.0, blue: 89.0/255.0, alpha: 1.0)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
workoutTitleLabel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Settings Cell") as! WorkoutTableViewCell
cell.workoutTitle.text = workoutTitleLabel[indexPath.row]
cell.mainContent.text = mainContentLabel[indexPath.row]
cell.secondaryContent.text = ""
(mainContentLabel[indexPath.row] == offTitle) ? (cell.mainContent.textColor = fontColorRed) : (cell.mainContent.textColor = fontColorBlack)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
selectedSetting?(indexPath.row)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
61
}
}
Your collection view cell should look like this.
class SettingsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var settingsTableView: UITableView!
}
This should then work. If you need to have a callback from the table view delegate / data source to your view controller managing your collection view, you can use a closure. In the example table view delegate the closure is called selectedSettings. In your view controller in viewDidLoad you define the call back for instance like this:
override func viewDidLoad() {
super.viewDidLoad()
settingsDelegate.selectedSetting = { [unowned self] selection in
startSettingsMenu(for: selection)
}
}
The result looks like this.
Kind regards,
MacUserT
In Tableview each row you can load UITableViewCell with pass collectionviewdata
//View Controller
var collectionView1Data = ["cell1", "cell2"]
var collectionView2Data = ["cell1", "cell2"]
//UITableviewDelegate Datasource
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//.....
if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") as? TableviewCell
cell.collectionData = collectionView1Data /// Collectionviewdata
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") as? TableviewCell
cell.collectionData = collectionView2Data
return cell
}
}
==============================
Each Tableviewcell contains CollectionView
//UITableViewCell
class TableviewCell: UITableViewCell {
#IBOutlet weak var collectionView: UICollectionView!
var collectionData: [String]? {
didSet {
guard collectionData != nil else {
return
}
collectionView.reloadData()
}
}
override func awakeFromNib() {
super.awakeFromNib()
collectionView.register(UINib(nibName: "collectionViewCell", bundle: nil), forCellWithReuseIdentifier: "collectionViewCell")
collectionView.dataSource = self
collectionView.delegate = self
}
}
extension TableviewCell: UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
collectionData.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? collectionViewCell
cell...
return cell
}
}

How to use a UISwitch to add and remove data from an Array of Data

I have a tableview with a UISwitch in each of the cells. What I am trying to do is that whenever the UISwitch is Toggled On, it adds that cell into an array and when the switch is Toggled Off it removes it. Right now it only adds and doesn't remove.
Once this is complete I need the CollectionView that is also within this ViewController to update and visually show the newStringArray Cells based on the number in that array and that also is able to appear and disappear based on the cells that have their UISwitch toggled on.
import UIKit
class NewMoveViewController: UIViewController {
private var stringSource = ["String 1,", "String 2", "String 3"]
var newStringArray = Array<String>()
private let tableView: UITableView = {
let tableView = UITableView()
tableView.rowHeight = 100
return tableView
}()
private var collectionView: UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 50, height: 50)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.register(NewMoveCollectionViewCell.self, forCellWithReuseIdentifier: NewMoveCollectionViewCell.identifier)
collectionView?.showsHorizontalScrollIndicator = false
title = "Add to Group"
tableView.register(NewMoveTableViewCell.self, forCellReuseIdentifier: NewMoveTableViewCell.identifier)
tableView.delegate = self
tableView.dataSource = self
collectionView?.backgroundColor = .systemBlue
collectionView?.dataSource = self
collectionView?.delegate = self
guard let myCollection = collectionView else {
return
}
view.addSubview(myCollection)
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = CGRect(x: 0, y: 100, width: view.frame.size.width, height: 50)
tableView.frame = CGRect(x: 0, y: 200, width: view.frame.size.width, height: view.frame.size.height)
}
}
extension NewMoveViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: NewMoveTableViewCell.identifier, for: indexPath) as! NewMoveTableViewCell
let switchView = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
switchView.tag = indexPath.row
switchView.addTarget(self, action: #selector(self.switchDidChange(_:)), for: .valueChanged)
cell.accessoryView = switchView
cell.configure(with: "", label: "test")
return cell
}
#objc func switchDidChange(_ sender: UISwitch) {
newStringArray.append(stringSource[sender.tag])
// newStringArray.remove(stringSource.remove(at: [s]))
print(newStringArray)
}
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false
}
}
extension NewMoveViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return newStringArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NewMoveCollectionViewCell.identifier, for: indexPath) as! NewMoveCollectionViewCell
return cell
}
}
the hardest part is to remove an object from an array, my approach on these situations is to transform my array in a NSMutableArray because it have a function to remove an specific object, then make a delegate in the cell that informs the viewController to remove the object from the list and reload the tableView.
the delegate wil be something like this:
protocol RemoveObjectFromCell {
func removeObjectIncell(object: MyObject)
}
class myCell: UITableViewCell {
//your outlets and variables
var object: MyObject?
var delegate: removeObjectIncell?
func setupCell(object: myObject) {
//configure your cell with the specific object
}
}
make sure of calling the delegate on the switch action inside you cell class like this:
#IBAction func switchPressed(sender: UISwitch) {
if !sender.isOn {
self.delegate?.removeObjectIncell(object: self.object)
}
in the view controller implement your protocol and use the required function like this:
class myViewController: UIViewController, RemoveObjectFromCell {
//everything that goes in your class
func removeObjectIncell(object: MyObject) {
self.myArray.remove(object)
DispatchQueue.main.async {
self.myTableView.reloadData()
}
}
}
In order to get changes you want you have to set property which is gonna indicate whether switch is on or off
Something like: var switchIsActive = false
and simply change it in function and if it is turned on you perform one action when it is off you perform another one. Also after function you have to reload your tableView tableView.reloadData()
You can remove elements in your array by their tag by calling Array.remove(at: Int). It can be done by the cells [indexPath.row]

UICollectionViewCell could not dequeue a view of kind : UICollectionElementKindCell with identifier

I am following Duc Tran's Tutorial on a collection (https://www.youtube.com/watch?v=vB-HKnhOgl8) and when I am running my application, I keep getting this error:
Thread 1: Exception: "could not dequeue a view of kind: UICollectionElementKindCell with identifier CHALLENGECELL - must register a nib or a class for the identifier or connect a prototype cell in a storyboard"
I looked at other solutions for this but none have yielded results.
Here is the code for the view controller that holds the collection
import UIKit
class ChallengesViewerViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!
//MARK: - UICollectionViewDataSource
private var challenges = WeeklyChallenges.createChallenge()
let cellScaling: CGFloat = 1.0
override func viewDidLoad() {
super.viewDidLoad()
let screenSize = UIScreen.main.bounds
let cellWidth = floor(screenSize.width * cellScaling)
let cellHeight = floor(screenSize.height * cellScaling)
let insetX = (view.bounds.width - cellWidth)/2
let insetY = (view.bounds.height - cellHeight)/2
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: cellWidth, height: cellHeight)
collectionView.contentInset = UIEdgeInsets(top: insetY, left: insetX, bottom: insetY, right: insetX)
collectionView.dataSource = self
}
}
extension ChallengesViewerViewController: UICollectionViewDataSource{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return challenges.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CHALLENGECELL", for: indexPath) as! ChallengeCollectionViewCell
cell.challenge = self.challenges[indexPath.item]
return cell
}
}
Additionally, here is the storyboard where I am assigning the reusable identifier to the collection view cell.
You have to register the cell that you're dequeuing in cellForItem in viewDidLoad.
override func viewDidLoad() {
super.viewDidLoad()
//...
collectionView.register(ChallengeCollectionViewCell.self, forCellWithReuseIdentifier: "CHALLENGECELL")
}
If you're using Nib use this instead:
let nib = UINib(nibName: <#T##String#>, bundle: nil)
collectionView.register(nib, forCellWithReuseIdentifier: "CHALLENGECELL")

UICollectionViewCell changes cell contents when scrolling

I have a custom UICollectionView. I am using a UIView instead of a UICollectionViewCell as I'm wanting to use the UIView elsewhere.
The UICollectionView scrolls only horizontally and has 14 cells; each with the UIView as its contents.
Inside this UIView is another UICollectionView which houses a UICollectionViewCell which is just an image of a dice.
So:
Outer UICollectionView with Cell
The cell has a UIView
The UIView has a UICollectionView and UICollectionViewCell
The UICollectionViewCell is just an imageView of a dice.
The problem I'm having is, when the UICollectionView scrolls horizontally, the contents of the cell are changing when they should remain static; sometimes it randomly moves the contents, or completely removes the contents.
I'm not sure what is causing this to happen.
How can I ensure that upon scrolling that the UICollectionView keeps its contents intact?
Outer UICollectionView:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allLocos?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell:OuterCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "OuterCollectionViewCell", for: indexPath) as! OuterCollectionViewCell
if cell.cardView == nil {
let arr = UINib(nibName: "CardView", bundle: nil).instantiate(withOwner: nil, options: nil)
let view = arr[0] as! CardView
cell.contentView.addSubview(view)
cell.cardView = view
}
if let locos = self.allLocos {
let loco:EYLocomotive = locos[indexPath.row]
print(indexPath.row, loco.name, loco.orders)
cell.engineCardView?.setup(loco:loco)
}
cell.layoutIfNeeded()
return cell
}
I think the issue is being caused by this line:
cell.engineCardView?.setup(loco:loco)
My UIView (The cardView) has this code:
#IBOutlet weak var diceCollectionView: UICollectionView!
var dice:[Int] = [Int]()
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup(loco:EYLocomotive) {
self.diceCollectionView.delegate = self
self.diceCollectionView.dataSource = self
self.diceCollectionView.allowsSelection = false
self.diceCollectionView.allowsMultipleSelection = false
self.diceCollectionView.isUserInteractionEnabled = false
self.diceCollectionView.showsVerticalScrollIndicator = false
self.diceCollectionView.showsHorizontalScrollIndicator = false
self.diceCollectionView.register(UINib(nibName: "EYDiceCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "EYDiceCollectionViewCell")
// add dummy dice for testing purposes only
for var _ in 1...3 {
let die = Die().roll
dice.append(die)
}
}
The diceCollectionView is the holder of the Dice Imagery.
When we get to to the UICollectionViewDelegate; in the same file;
// MARK: Collection View Delegate
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dice.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: EYDiceCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "EYDiceCollectionViewCell", for: indexPath) as! EYDiceCollectionViewCell
let dieValue = self.dice[indexPath.row] as Int
let imageFile:String = "die-face-\(dieValue)"
cell.imageView.image = UIImage(named: imageFile)
cell.layoutIfNeeded()
return cell
}
The UICollectionView works fine, the problem comes when I start scrolling horizontally out of the viewport and then scroll back.
Contents of the cell change.
Contents of the cell sometimes change to a different one to the one I'm expecting
Contents of the cell sometimes disappear upon scrolling
What I'd like to know is how can I ensure the contents do not change?
With thanks

UICollectionViewCell Segue Triggered Only on Multiple Selection

I've been working on this issue for the better part of a few days. I am attempting to segue from a UICollectionViewCell to a ViewController. While I understand how to do this, the segue is only triggered by selecting multiple cells (i.e. two or more taps, but must include different cells and not be outside of the CollectionView).
How can I alter my code to ensure that the segue happens only for one cell without the need to select more than one cell at a time (i.e. a normal segue, tap on Cell to segue).
What I've done so far:
Set up a Show segue from the UICollectionViewCell to the ViewController.
Implemented the CollectionView method didSelectItemAtIndexPath and prepareForSegue to pass data to the destination.
Disabled multiple section every object, to include the CollectionView, the Cell, and the items in the Cell.
Ensured that "User Interaction Enabled" on all the aforementioned fields.
Cell and Push segue have appropriate reuse ID.
My code for my CollectionViewController is as follows:
let reuseID = "HighscoreReuser"
#IBOutlet var addressBar: UISearchBar!
var noUsernameErrorMessage: UIAlertController = UIAlertController()
var pageLoadErrorMessage: UIAlertController = UIAlertController()
var noUsernameCount: Int = 0
var currentPlayer: Player = Player()
var titles = [String]()
var levelArray: [Int] = [Int]()
let sectionInsets = UIEdgeInsets(top: 20.0, left: 0.0, bottom: 0.0, right: 0.0)
override func viewDidLoad() {
super.viewDidLoad()
var tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
self.collectionView?.addGestureRecognizer(tap)
titles = ["Lots of strings be here."]
addressBar = UISearchBar(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width - 30, 20))
addressBar.delegate = self
addressBar.showsScopeBar = true
var leftNavBarButton = UIBarButtonItem(customView: addressBar)
self.navigationItem.leftBarButtonItem = leftNavBarButton
var cellHeight = 85.0
var cellWidth = UIScreen.mainScreen().bounds.width / 3
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 23
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseID, forIndexPath: indexPath) as CollectionViewCell
cell.levelLabel.text = self.titles[indexPath.row]
let curr = indexPath.row + 1
println(curr)
let imgName = "skill\(curr).png"
cell.skillPicture.image = UIImage(named: imgName)
cell.frame.size.height = 85.0
cell.frame.size.width = UIScreen.mainScreen().bounds.width / 3
return cell
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
return CGSize(width: UIScreen.mainScreen().bounds.width / 3, height: 85.0)
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//not needed if placed in storyboard
//self.performSegueWithIdentifier("PushToCalc", sender: indexPath)
println("tapped")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PushToCalc" {
let indexPaths: NSArray = self.collectionView!.indexPathsForSelectedItems()
let indexPath: NSIndexPath = indexPaths[0] as NSIndexPath
println(indexPath)
let destination = segue.destinationViewController as UIViewController
destination.navigationItem.title = String(indexPath.item)
}
}
.... and my CollectionViewCell, if it matters:
import Foundation
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var skillPicture: UIImageView!
#IBOutlet weak var levelLabel: UILabel!
}
I think you have to set cancelsTouchesInView to false to let the gesture recognizer allow your touch to pass through.
So under your var tap:UITapGestureRecognizer declaration try adding
tap.cancelsTouchesInView = false