I want to transition another ViewController Class when tablViewCell tapped. (TableView in CollectionView Cell)
so,I want to write to transition Code in tableViewCell Class.
How should I do?
You need to assign collectionview delegate to the view controller class inside the tableview cellforrow method. And assign tableview cell indexpath.row to its collectionview tag.
In collectionview didselect method write the transition Code.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ...
cell.collectionView.tag = indexPath.row
cell.collectionView.delegate = self
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("selected collectionview cell indexpath \(indexPath) in table view cell row \(collectionView.tag)")
//push to next view controller from here
}
}
Related
I have a tableView, which cell's contains collectionView. Now I want to get the tableview row index when I select any cell of collection view cell
Create a subclass of UICollectionView and add an attribute to it.
class MyCustomCollectionView: UICollectionView {
var parentTableViewIndexPath: IndexPath?
}
Use this collection view in your tableview cell
class MyCustomTableViewCell: UITableViewCell {
#IBOutlet weak var customCollectionView: MyCustomCollectionView!
}
In your table's cellForRow method, set the indexPath attribute
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "IDENTIFIER", for: indexPath) as! MyCustomTableViewCell
cell.customCollectionView.parentTableViewIndexPath = indexPath
//Any additional customisation
return cell
}
In your collectionView's didSelectItemAt, access the indexPath like this
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let tableIndexPath = (collectionView as? MyCustomCollectionView)?.parentTableViewIndexPath else { return }
}
Inside cellForRowAt
cell.collectionView.tag = indexPath.row
I am trying to make a to-do list app and I am having trouble trying to add subtasks to my main to-do tasks. I have a button inside each table view cell, when this button is pressed I want it to add another table view cell that I can type and save a "subtask" on.
//set up tableView row amount
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return taskData.count
}
//set up what is in the tableView row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//This is for a main task
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! CustomTableViewCell
cell.label.text = taskData[indexPath.row]
return cell
}
Use delegates to pass data from cells to your ViewController, and reload the tableView.
CustomTableViewCell:
protocol CustomTableViewCellDelegate: class {
func customTableViewCellButtonClicked(_ cell: CustomTableViewCell)
}
class CustomTableViewCell: UITableViewCell {
weak var delegate: CustomTableViewCellDelegate?
func buttonClicked() {
self.delegate?.customTableViewCellButtonClicked(self)
}
}
ViewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! CustomTableViewCell
cell.label.text = taskData[indexPath.row]
cell.delegate = self
return cell
}
func customTableViewCellButtonClicked(_ cell: CustomTableViewCell) {
// add the task you need from that cell to your tasks list.
taskData.append(....)
//reload your tableView
self.tableView.reloadData()
}
I have two classes: CollectionCell and ViewController.
The first class is used for Collection View Cell (in which I have placed a button). In CollectionCell class I need to connect outlet for this button: #IBOutlet weak var firstPercent: UIButton!.
In ViewController class I need to use var of this button: firstPercent.
How can I do that? Thanks for any help.
In collectionViewDelegate
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Now declare your Custom Cell instance and then
you can use CollectionCell.firstPercent addTarget in ViewController and set this or
do whatever you want.
You can get it something like below.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ZonesCell", for: indexPath as IndexPath) as! ZonesCell
let keyValue = self.dataList[indexPath.row] as! [String:Any]
cell.lblZoneName.text = keyValue[Keys.name] as? String
if(keyValue[Keys.status] as? Bool)! {
cell.lblZoneName.textColor = UIColor.white
} else {
cell.lblZoneName.textColor = UIColor.red
}
return cell
}
There lets suppose ZonesCell is the collectionCell contains lblZoneName as label.
You can use button same as label.
You can use delegate for this.
Add a protocol named “CollectionCellDelegate“ for your cell and add a delegate method for your button action. Pass cell itself as a parameter to that method. Conform to “CollectionCellDelegate“ from your ViewController and implement delegate method inside ViewController. Finally but most important step, assign your view controller as CollectionCellDelegate from cellForItemAt method.
protocol CollectionCellDelegate : class {
func didPressButtonFirstPercent(_ cell: CollectionCell)
}
//Inside your CollectionCell class declare a variable to hold your cell delegate
class CollectionCell: UICollectionViewCell {
//Add a variable to hold your delegate
weak var delegate: CollectionCellDelegate?
//Outlet for your button
#IBOutlet weak var firstPercent: UIButton!
//Action for your button
#IBAction func didPressButtonFirstPercent(_ sender: Any) {
delegate?.didPressButtonFirstPercent(self)
}
}
//ViewController Conform to CollectionCellDelegate
class ViewController: UIViewController, CollectionCellDelegate{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: “Cell_Identifier”, for: indexPath) as! CollectionCell
//Set ViewController as your CollectionCell delegate
cell.delegate = self
return cell
}
//Implement delegate method here
func didPressButtonFirstPercent(_ cell: CollectionCell) {
//You can access your button here like below
Let firstPercent = cell.firstPercent
}
}
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// get a reference to our storyboard cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! CollectionCell
// Use the outlet in our custom class to get a reference to the UILabel in the cell
cell. firstPercent.tag = indexPath.row
example project
return cell
}
}
So I am trying to push a UITableViewController from a UITableViewCell that is embedded in a collection view cell.
So the structure is UICollectionView > UICollectionViewCell > UITableView > UITableViewCell.
Do I want to call a segue when the TableViewCell is clicked?
How can I do this as you cannot access the function perform segue for identifier?
You can create one protocol for that and implement it with your ViewController where you are having collectionView, after that make instance property of that protocol in your collectionViewCell and set that property in cellForItemAt method. Now inside the didSelectRowAt method of tableView call the delegate method with the detail that you want to pass for segue.
protocol PassData {
func performSegue(with data: String) //Set argument type to Type that you want pass instead of String
}
Now implement this PassData protocol with your ViewController and inside the cellForItemAt set the delegate of UICollectionViewCell.
class ViewController: UIViewController, PassData, UICollectionViewDelegate, UICollectionViewDataSource {
//Other methods
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCollectionViewCell
cell.passDelegate = self
return cell
}
//Add the `performSegue(with:)` delegate method of PassData
func performSegue(with data: String) {
//Perform segue here
self.performSegue(withIdentifier: "SegueIdentifier", sender: data)
}
}
Now in your CustomCollectionViewCell make one instance property named passDelegate of type PassData? after that in didSelectRowAt method of tableView call its delegate method.
class CustomCollectionViewCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
var passDelegate: PassData?
//Your other methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Pass whatever data that you want to pass
self.passDelegate?.performSegue(with: array[indexPath.row])
}
}
You can push the tableViewController to navigation stack by calling self.navigationController?.pushViewController(tableviewVC, animate: true) from table view delegate method didSelectRowAtIndexPath
I want to dynamically add collection view inside tableview. I have make following code.
A cell class for collectionview
class NewsFeedCollectionViewCell : UICollectionViewCell{
#IBOutlet weak var imageViewSlider: UIImageView!
}
Than assign collectionview in Tableview cellforrow at indexpath
cell.collectionViewNewsFeed.tag = indexPath.row
cell.collectionViewNewsFeed.reloadData()
Than added following delegates of collectionview
// MARK: - Collection view Delegates / Datasources
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (mutableArrayNewsFeed[collectionView.tag]["images"] as! NSArray).count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("NewsFeedCollectionViewCell", forIndexPath: indexPath) as! NewsFeedCollectionViewCell
print("tag : \(collectionView.tag) , Row : \(indexPath.row)")
let img = (mutableArrayNewsFeed[collectionView.tag]["images"] as! NSArray)[indexPath.row] as? String ?? "imgLoginScreenLogo"
cell.imageViewSlider.image = UIImage(named: img)
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("Collection View Row : \(indexPath.row)")
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
return collectionView.frame.size
}
Its adjusting properly but the indexes gets changes while i scroll the collectionview. For ex, I scroll collectionview upto 3 cell than i go to the tableview 4th index than it also set the index of 4th index of collectionview to 3rd.
Simply want to add collection view with multiple images inside Table view. I have added, but after scrolling the collection view to 3rd image on 1st cell of tableview, i move to 4th cell of Tableview, there also the collectionview gets scrolled automatically upto 4th cell.
Need to get out of this.
There was an issue with the indexpath, I get the solution by keeping the indexpath in an array.
Refer Following link
https://github.com/ashfurrow/Collection-View-in-a-Table-View-Cell