I have an issue with a collectionView inside a TableVieCell. When i tap on a collectionCell, didSelectItemAt doesn´t get called. I have a button in the collectionCell so i tried to disable the user interaction and enable the contentView userInteraction but it didn't work.
The red rectangle is the tableCell and the blue rectangle is the collecionView insede the table view cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "MedCellWithCollection") as? MedCellWithCollection{
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.white.withAlphaComponent(0.0)
cell.selectedBackgroundView = backgroundView
cell.setMedName(name: self.medCatalog[indexPath.row].nombre, uso: self.medCatalog[indexPath.row].uso , array: self.medCatalog[indexPath.row].enfermedades[0].aplicaciones , index: indexPath.row)
cell.layoutIfNeeded()
cell.layoutSubviews()
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
return cell
}
}
return UITableViewCell()
}
The tableCell
class MedCellWithCollection: UITableViewCell {
//Outlets
#IBOutlet weak var medText: UILabel!
#IBOutlet weak var uso: UILabel!
#IBOutlet weak var arrowIcon: UIImageView!
#IBOutlet weak var CollectionView: UICollectionView!
//Variables
var dosesType:[Aplicacion]?
override func awakeFromNib() {
super.awakeFromNib()
self.collectionViewSetUp()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setMedName(name: String, uso: String, array: [Aplicacion], index: Int){
self.medText.text = name
self.uso.text = uso
self.dosesType = array
self.CollectionView.reloadData()
}
}
extension MedCellWithCollection: UICollectionViewDataSource, UICollectionViewDelegate{
func collectionViewSetUp(){
self.CollectionView.delegate = self
self.CollectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.dosesType?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "doseColletion", for: indexPath as IndexPath) as? DoseCollection {
cell.setButtonConfig(doseType: self.dosesType![indexPath.row].metodo , index: indexPath.row)
return cell
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("tapped")
}
}
CollectionCell
import UIKit
class DoseCollection: UICollectionViewCell {
//Outlets
#IBOutlet weak var Button: Button!
//Variables
let constants = Constants()
func setButtonConfig(doseType: String, index: Int){
self.Button.titleLabel?.text = doseType
self.Button.backgroundColor = constants.COLOR_ARRAY[index]
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func layoutIfNeeded() {
super.layoutIfNeeded()
}
}
Potential Solutions:
1) Should be Single Selection for tableView selection property, programmatically it can be done by tableView.allowsSelection = true
2) The class is not the UITableViewDelegate for that table view, though UITableViewController is supposed to set that automatically.
tableView?.delegate = self
3) If the problem arise with UITapGestureRecognizer:
let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
BOL :)
In my case, I want to change the background of the button in other words the background of the cell in the collection view:
class CustomCVCell: UICollectionViewCell {
override var isSelected: Bool {
didSet {
grayBackgroundViewWithImage.image =
isSelected ? UIImage(named: "") : UIImage()
}
}
In the main class where the collection view is stored create this variable:
class CustomViewController: UIViewController {
///save the indexPath of last selected cell
private var lastSelectedIndexPath: IndexPath? }
In viewDidLoad() set this value to false:
customCollectionView.allowsMultipleSelection = false
Further code in data source. In my case, the first cell should be is selected:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCVCell.cellID(),
for: indexPath) as! CustomCVCell
if indexPath.row == 0 {
lastSelectedIndexPath = indexPath
cell.isSelected = true
}
//update last select state from lastSelectedIndexPath
cell.isSelected = (lastSelectedIndexPath == indexPath)
return cell
}
Further code in the delegate:
///UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard lastSelectedIndexPath != indexPath else { return }
if let index = lastSelectedIndexPath {
let cell = collectionView.cellForItem(at: index) as! CustomCVCell
cell.isSelected = false
}
let cell = collectionView.cellForItem(at: indexPath) as! CustomCVCell
cell.isSelected = true
lastSelectedIndexPath = indexPath
}
Related
I am using storyboards, and my UICollectionView with a basic custom cell is not showing at all? My simulator is constantly running a version of my storyboard when my "Next" button was at the middle of the screen, obviously now it is at the bottom as shown here along with all the identities and links created in the storyboard: https://imgur.com/a/R8iTm9n
import UIKit
class CategoryViewController: UIViewController{
#IBOutlet weak var categoryCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
categoryCollectionView.delegate = self
categoryCollectionView.dataSource = self
NetworkingClient.fetchRecipeCategories{ (recipeCategories) in
//print(recipeCategories)
}
categoryCollectionView.reloadData()
}
}
extension CategoryViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
print("Taptaptap")
}
}
extension CategoryViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 12
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = UICollectionViewCell()
if let testCell = collectionView.dequeueReusableCell(withReuseIdentifier: "categoryCell", for: indexPath) as? CategoryCollectionViewCell{
testCell.configure(with: indexPath.row)
cell = testCell
print("test1")
}
print("test2")
return cell
}
}
/*
extension CategoryViewController: UICollectionViewDelegateFlowLayout {
}
*/
And my my custom view cell :
class CategoryCollectionViewCell: UICollectionViewCell {
static let identifier: String = "CategoryCollectionViewCell"
#IBOutlet weak var categoryImageView: UIImageView!
#IBOutlet private weak var testLabel: UILabel!
func configure(with id: Int){
testLabel.text = String(id)
categoryImageView.clipsToBounds = true
categoryImageView.contentMode = .scaleAspectFit
}
}
Sorry for the formatting...
Register your custom collectionview cell named "categoryCell" in viewDidLoad()
categoryCollectionView.register(UINib(nibName: "categoryCell", bundle:
nil),forCellWithReuseIdentifier: "categoryCell")
categoryCollectionView.delegate = self
categoryCollectionView.dataSource = self
categoryCollectionView.reloadData()
I have created a carousel view using UPCarouselFlowLayout and it works well. But when the UIButton in the view is clicked, no action occurs. How do I make it so that when the UIButton is clicked, it calls a particular action?
CollectionViewCell:
class MagicCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var magicview: UIView!
#IBOutlet weak var magicimage: UIImageView!
#IBOutlet weak var magiclabel: UILabel!
#IBOutlet weak var magicbutton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
self.magicview.isUserInteractionEnabled = true
// Initialization code
DispatchQueue.main.async {
self.magicview.layer.shadowColor = UIColor.gray.cgColor
self.magicview.layer.shadowOpacity = 0.5
self.magicview.layer.shadowOpacity = 10.0
self.magicview.layer.shadowOffset = .zero
self.magicview.layer.shadowPath = UIBezierPath(rect: self.magicview.bounds).cgPath
self.magicview.layer.shouldRasterize = false
}
}
}
Magic1.swift
import UPCarouselFlowLayout
class Magic1: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var magiccollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
magiccollection.register(UINib.init(nibName: "MagicCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "magiccidentifier")
let floawLayout = UPCarouselFlowLayout()
floawLayout.itemSize = CGSize(width: UIScreen.main.bounds.width - 60.0, height: magiccollection.frame.size.height)
floawLayout.scrollDirection = .horizontal
floawLayout.sideItemScale = 0.8
floawLayout.sideItemAlpha = 1.0
floawLayout.spacingMode = .fixed(spacing: 5.0)
magiccollection.collectionViewLayout = floawLayout
magiccollection.delegate = self
magiccollection.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = sexeducollec.dequeueReusableCell(withReuseIdentifier: "magiccidentifier", for: indexPath) as!MagicCollectionViewCell
if indexPath.row == 0{
cell.magiclabel.text = "Tester title"
cell.sexedimage.image = #imageLiteral(resourceName: "merlin")
}else if indexPath.row == 1{
cell.magiclabel.text = "love is in the air"
}else{
cell.magiclabel.text = "Title - \(indexPath.row + 1)"
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0{
print("Accio")
}else if indexPath.row == 1{
print("alohamora")
}
}
}
What I'm trying to do is when magicbutton is clicked at indexPath.row == 0 it calls a specific action and when it is clicked at indexPath.row == 1 it calls a specific function.
Try this approach! Also, You can call closure at IBAction
class ViewController: UICollectionViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "magiccidentifier", for: indexPath) as? MagicCollectionViewCell {
switch indexPath.row {
case 0:
cell.onCellTouched = { print("Hi")}
default:
cell.onCellTouched = { print("By") }
}
return cell
}
return UICollectionViewCell()
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let item = collectionView.cellForItem(at: indexPath) as? MagicCollectionViewCell
item?.onCellTouched()
}
}
class MagicCollectionViewCell: UICollectionViewCell {
var onCellTouched: () -> Void = { assertionFailure("Cell action didn't set up") }
override func awakeFromNib() {
super.awakeFromNib()
self.backgroundColor = .black
}
}
You are missing an IBAction of your button in MagicCollectionViewCell. So add an action for your button:
#IBAction func buttonAction(_ sender: UIButton) {
}
I have an UICollectionView in which I want only want 1 cell to be active. With active I mean: the last cell that has been clicked (or the very first cell when to collection view lays out). When a user clicks a non-active cell, I want to reset the old active cell to a non-active state. I am having trouble doing this. This is because visibleCells, a property of collection view, only returns the cells on screen but not the cells in memory. This is my current way to locate an active cell and reset the state to non active.
This scenario can happen, causing multiple active cells: A user scroll slightly down so that the current active cell is not visible anymore, taps on a random cell and scroll up. The problem is that the old active cell stays in memory, although it is not visible: cellForItemAt(_:) does not gets called for that cell. Bad news is that visibleCells also do not find the old active cell. How can I find it? The function willDisplay cell also does not work.
An example project can be cloned directly into xCode: https://github.com/Jasperav/CollectionViewActiveIndex.
This is the code in the example project:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var collectionView: CollectionView!
static var activeIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.go()
}
}
class Cell: UICollectionViewCell {
#IBOutlet weak var button: MyButton!
}
class CollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {
func go() {
delegate = self
dataSource = self
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
if indexPath.row == ViewController.activeIndex {
cell.button.setTitle("active", for: .normal)
} else {
cell.button.setTitle("not active", for: .normal)
}
cell.button.addTarget(self, action: #selector(touchUpInside(_:)), for: .touchUpInside)
return cell
}
#objc private func touchUpInside(_ sender: UIButton){
let hitPoint = sender.convert(CGPoint.zero, to: self)
guard let indexPath = indexPathForItem(at: hitPoint), let cell = cellForItem(at: indexPath) as? Cell else { return }
// This is the problem. It does not finds the current active cell
// if it is just out of bounds. Because it is in memory, cellForItemAt: does not gets called
if let oldCell = (visibleCells as! [Cell]).first(where: { $0.button.titleLabel!.text == "active" }) {
oldCell.button.setTitle("not active", for: .normal)
}
cell.button.setTitle("active", for: .normal)
ViewController.activeIndex = indexPath.row
}
}
To recover from this glitch you can try in cellForRowAt
cell.button.tag = indexPath.row
when the button is clicked set
ViewController.activeIndex = sender.tag
self.reloadData()
You can use the isSelected property of the UIColectionViewCell. You can set an active layout to your cell if it is selected. The selection mechanism is implemented by default in the UIColectionViewCell. If you want to select/activate more than one cell you can set the property allowsMultipleSelection to true.
Basically this approach will look like this:
class ViewController: UIViewController {
#IBOutlet weak var collectionView: CollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.go()
}
func activeIndex()->Int?{
if let selectedItems = self.collectionView.indexPathsForSelectedItems {
if selectedItems.count > 0{
return selectedItems[0].row
}
}
return nil
}
}
class Cell: UICollectionViewCell {
#IBOutlet weak var myLabel: UILabel!
override var isSelected: Bool{
didSet{
if self.isSelected
{
myLabel.text = "active"
}
else
{
myLabel.text = "not active"
}
}
}
}
class CollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {
func go() {
delegate = self
dataSource = self
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
return cell
}
}
I have a button which selects all cells in the collectionview. Once clicked, the button function changes so that all cells will be de-selected upon pressing it again.
So far so good.. But
1) When you select all cells with the button, scroll a bit down and to the top again
2) Then de-select all cells with the button, and select all cells with the button again
3) And start scrolling down, some cells (mostly 1-2 complete rows, later cells are fine again) are not properly updated, so they don't appear with the selected state which is a different background color. Seems like an issue with dequeueReusableCell, but I can't wrap my head around it..
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if cell.isSelected {
cell.backgroundColor = UIColor.green
} else {
cell.backgroundColor = UIColor.white
}
if cell.viewWithTag(1) != nil {
let cellTitle = cell.viewWithTag(1) as! UILabel
cellTitle.text = String(indexPath.row)
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let cell = collectionView.cellForItem(at: indexPath) {
cell.backgroundColor = UIColor.green
selectedCells.append(indexPath.row)
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if let cell = collectionView.cellForItem(at: indexPath) {
cell.backgroundColor = UIColor.white
selectedCells.removeObject(indexPath.row)
}
}
And the action method for handling button clicking
#IBAction func selectButtonTapped(_ sender: Any) {
if isSelectAllActive {
// Deselect all cells
selectedCells.removeAll()
for indexPath: IndexPath in collectionView!.indexPathsForSelectedItems! {
collectionView!.deselectItem(at: indexPath, animated: false)
collectionView(collectionView!, didDeselectItemAt: indexPath)
let cell: UICollectionViewCell
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CVCell", for: indexPath)
}
selectButton.title = "Select all"
isSelectAllActive = false
} else {
// Select all cells
for i in 0 ..< collectionView!.numberOfItems(inSection: 0) {
collectionView!.selectItem(at: IndexPath(item: i, section: 0), animated: false, scrollPosition: UICollectionViewScrollPosition())
collectionView(collectionView!, didSelectItemAt: IndexPath(item: i, section: 0))
}
selectedCells.removeAll()
let indexPaths: [IndexPath] = collectionView.indexPathsForSelectedItems!
for item in indexPaths {
selectedCells.append(item.row)
}
selectedCells.sort{$0 < $1}
selectButton.title = "Select none"
isSelectAllActive = true
}
}
And for completion the array extension for removing an object
extension Array where Element : Equatable {
mutating func removeObject(_ object : Iterator.Element) {
if let index = self.index(of: object) {
self.remove(at: index)
}
}
}
Complete Xcode project can be found here: https://www.dropbox.com/s/uaj1asg43z7bl2a/SelectAllCells.zip
Used Xcode 9.0 beta 1, with iOS11 Simulator/iPhone SE
Thanks for your help!
Your code is a little confused because you are trying to keep track of cell selection state both in an array and in the cell itself.
I would just use a Set<IndexPath> as it is simpler and more efficient than an array. You can then refer to this set when returning a cell in cellForItemAt: and you don't need to do anything in willDisplay.
When you select/deselect all you can just reload the whole collection view and when an individual cell is selected/deselected, just reload that cell.
#objcMembers
class MainViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet var collectionView: UICollectionView!
#IBOutlet var toolBar: UIToolbar?
#IBOutlet weak var selectButton: UIBarButtonItem!
var selectedCells = Set<IndexPath>()
var isSelectAllActive = false
// MARK: - Classes
override func viewDidLoad() {
super.viewDidLoad()
// Collection view
collectionView!.delegate = self
collectionView!.dataSource = self
collectionView!.allowsMultipleSelection = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
#IBAction func selectButtonTapped(_ sender: Any) {
if isSelectAllActive {
// Deselect all cells
selectedCells.removeAll()
selectButton.title = "Select all"
isSelectAllActive = false
} else {
// Select all cells
for i in 0 ..< collectionView!.numberOfItems(inSection: 0) {
self.selectedCells.insert(IndexPath(item:i, section:0))
}
selectButton.title = "Select none"
isSelectAllActive = true
}
self.collectionView.reloadData()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 50
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: UICollectionViewCell
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CVCell", for: indexPath)
if self.selectedCells.contains(indexPath) {
cell.backgroundColor = .green
} else {
cell.backgroundColor = .white
}
if cell.viewWithTag(1) != nil {
let cellTitle = cell.viewWithTag(1) as! UILabel
cellTitle.text = String(indexPath.row)
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("\ndidSelectItemAt: \(indexPath.row)")
if selectedCells.contains(indexPath) {
selectedCells.remove(indexPath)
} else {
selectedCells.insert(indexPath)
}
self.collectionView.deselectItem(at: indexPath, animated: false)
self.collectionView.reloadItems(at: [indexPath])
print("selectedCells: \(selectedCells)")
}
}
I'm really new in iOS/Swift and i'm in a small project. In this project i have a UITableView inside ViewController. And i have another file custom CollectionViewCell in side UITableViewCell.
I want when user click a cell in collectionview it will open another ViewController and it get data from this collectionviewcell.
This is my uitableview swift file:
class IndexRow: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var names:[String] = ["Movie 1","Movie 2","Movie 3","Movie 4","Movie 5","Movie 6"]
#IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
collectionView.registerClass(indexOneMovie.self, forCellWithReuseIdentifier: "onemovie")
let nib = UINib(nibName: "indexOneMovie",bundle: nil)
collectionView.registerNib(nib, forCellWithReuseIdentifier: "onemovie")
self.collectionView.backgroundColor = UIColor.clearColor()
self.collectionView.delegate = self
self.collectionView.dataSource = self
print("Hello")
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return names.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("onemovie", forIndexPath: indexPath) as! indexOneMovie
cell.poster.image = UIImage(named: "poster.jpg")
cell.name.text = names[indexPath.row]
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print(indexPath.item)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let itemsPerRow:CGFloat = 2
let hardCodedPadding:CGFloat = 0
let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
let itemHeight = collectionView.bounds.height - (hardCodedPadding)
return CGSize(width: itemWidth, height: itemHeight)
}
How i can do it?
ok i have recently implemented the same in my app these are the links where i refered initially -
https://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell-in-swift/
http://www.thorntech.com/2015/08/want-your-swift-app-to-scroll-in-two-directions-like-netflix-heres-how/
you are making uicollectionview delegate confirms to uitableview cell so you cannot present or push to other view controller.
here is my code hope it will help you
homeController.swift which contains uitableview
extension HomeController : UITableViewDelegate {
func tableView(tableView: UITableView,willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewCell else { return }
//here setting the uitableview cell contains collectionview delgate conform to viewcontroller
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row, andForSection: indexPath.section)
tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}
func tableView(tableView: UITableView,didEndDisplayingCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewCell else { return }
storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
}
}
extension HomeController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
let element : [CollectionViewElement] = self.returnCollectionViewElementAccordingToIndex(collectionView.tag)
return element.count
}
func collectionView(collectionView: UICollectionView,cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",forIndexPath: indexPath) as! horizontalCollectionViewCell
let element : [CollectionViewElement] = self.returnCollectionViewElementAccordingToIndex(collectionView.tag)
cell.cellTitleLabel.text = element[indexPath.row].videos.title
cell.cellGenerLabel.text = element[indexPath.row].videos.gener
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
print("collectionviewtag:\(collectionView.tag) + indexpathrow:\(indexPath.row)")
//from here you can do push or present to anyview controller
// collectionviewtag is tableView cell row value and indexpathrow return collectionView cell row value.
}
}
TableViewCell.swift :custom UITableViewCell which contains collectionView
class TableViewCell: UITableViewCell {
#IBOutlet private weak var collectionView: UICollectionView!
#IBOutlet weak var cellLabel: UILabel!
#IBOutlet weak var cellButton: UIButton!
#IBAction func CellButtonActionTry(sender: UIButton) {
print("Dude \(cellButton.tag)")
}
var collectionViewOffset: CGFloat {
get {
return collectionView.contentOffset.x
}
set {
collectionView.contentOffset.x = newValue
}
}
func setCollectionViewDataSourceDelegate<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
(dataSourceDelegate: D, forRow row: Int , andForSection section : Int) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.tag = row // tableView indexpathrow equals cell tag
collectionView.reloadData()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
You can do it like this :
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print(indexPath.item)
let name = names[indexPath.item]
let distinationViewController = DistinationViewController()
distinationViewController.name = name
if let navVC: UINavigationController = UIApplication.sharedApplication().keyWindow?.rootViewController as? UINavigationController {
navVC.pushViewController(distinationViewController, animated: true)
}
}
This is just a way to do it i dont know which view you want to push or what your names array contains so kindly change those things accordingly.
get root navigationcontroller from uiapplication and perform push on it.