TableView Cell click to another TableView - uitableview

I have a tableView on my App. I want to click on a cell and go to another tableView. For example a list of Artists and then list of albums.
Normally I just drag the "Prototype Cells" to the other view controller. But nothing happens.
Here is my code:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return NumberOfArtists
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
print(NameOfArtist)
cell.textLabel?.text = NameOfArtist[indexPath.row]
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
Here is my Storyboard:
UPDATE: I've removed the segue from the TableView (the one that is on the back). Still not working.
Steps
1 - Create a tableView and add source and delegate.
2 - Create another View Controller and add a tableView.
3 - Create a segue from the first prototype cell to the second tableView.
Nothing happens.

I checked out your code you posted to Dropbox. Here's what's wrong with your code :
You need to embed your Main view controller in a navigation controller. You can do this by clicking on your Main view controller in the storyboard and then clicking the Editor-> Embed in -> Navigation controller option.
The cell you create in your cellForRowAtIndexPath method is not the same as the cell you attached the segue to in your storyboard. You create the cell like so :
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
This actually creates an entirely new cell with the reuse identifier "Cell". It doesn't have the segue attached to it. To do that :
let cell : UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("Cell");
This will get the cell in your storyboard.
Hope this helps.

Edited 8/13/15
You have to create a UITableView as you mentioned for example for the artists.
You create it you want another UITableView for the albums' artists.
You just have to link the segue from the prototype cell or from all the static cells to the UITableView and it should work.
Note : This is how to manage your storyboard. I have not included how to populate the data and to manage the UITableView

I think you don't need two viewController, as per your design you can use First tableView and Cell for both Artist & Album Controller.
You just need Two DataSource 1 for artist and other for Album and one boolean that manage Current Visible DataSource.than using tableView Delegate Methods you can manage Both Artist And Album View..
ex:
suppose our boolean Name is isArtist and isArtist = true for Artist View and isArtist = false for Album View.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isartist ? ArtistDataSource.Count : AlbumDataSource.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
if isArtist {
cell.textLabel?.text = ArtistDataSource[indexPath.row]
}
else {
cell.textLabel?.text = AlbumDataSource[indexPath.row]
}
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if isArtist {
isartist.toggle()
yourtableView.reloadData
}
else {
//Do what you wish for Album tableView Selection
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return isartist ? 70 : 100
}

Related

How to display a UItableView in UicollectionViewCell?

So I have collection view with 3 cells, each of which has a tableview in it. Obviously, each collection view cell has to load it's table view with different data for the table view cells.
My first thought was to make the collection view the delegate and datasrouce of the table view, but even so, the datasource will need to know which collection view cell is being loaded.
Also thought of making a separate class for the DS and delegate for both the collection view and the table view, but then again, I'm stuck on how the tableview DS will know which collection view cell it's being loaded from.
Any thoughts?
EDIT:
After I make the assignment, the datasource field is nil. So what am I missing here?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) else {
return UICollectionViewCell.init()
}
cell.backgroundColor = UIColor.clear
cell.theTableView.dataSource = RequestedTableDataSource.init()
cell.theTableView.delegate = self
cell.theTableView.reloadData()
return cell
}
class RequestedTableDataSource: NSObject, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 16
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "RequestedCell") as? IntervieologistRequestedCell else {
return UITableViewCell.init()
}
cell.setupCellFor(name: "Dan", image: UIImage.init(named: "dan")!)
return cell
}
}
If I do this:
let foo = RequestedTableDataSource.init()
cell.myTableView.dataSource = foo
then the dataSource field is set, numberOfRows gets called, but cellForRowAtIndexPath doesn't.
You can set the tableView.tag to an unique integer and identify it later in the delegate methods using that, but I would recommend keeping a seperate datasource/delegate for each tableview, much cleaner.
Don't make the CollectionView or any other View object the datasource/delegate.
eg set
collectionViewCell.tableView.tag = index;
collectionViewCell.tableView.delegate = commonDelegate;
or
collectionViewCell.tableView.delegate = uniqueDelegate; // Better choice

Swift 3.0 Using a Table View to Show and Add Comments

I am interested in having a tableview for comments (something similar to instagram comments). So far, I have used a custom cell to set up a textView for comments in my set array, dataName. I was wondering how I could go about setting up a textfield and button on the last row of the tableview that would act as the place to input more comments. Do I need to create another customcell for this and implement this in cellForRowAt indexPath ?
var comments = ["I like this item","Where did you get this?", "I can't believe you found this!", "Hello", "Yay"]
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.commentView.text = dataName[indexPath.row]
cell.commentView.textColor = UIColor.lightGray
cell.commentView.isEditable = false
cell.commentView.isScrollEnabled = false
return cell
}
You can accomplish you desired effect by adding a view that contains a text field and a button as the footer view of the tableview. And when a new comment is added you will proceed to add the comment to the array, and reload the tableview or insertRow with animation.
You already have one cell prototype called "Cell". Just add another cell prototype called "Comment". Now you have two cell prototypes with two different identifiers. If you're on the last row, ask for the "Comment" cell prototype in your dequeue call.

CollectionView inside Tableview, error with datasource

i have a uiviewcontroller, where i put a uitableview, with custom cells. Each of these cells, have inside a uicollectionview, with a horizontal scrolling.
I am working programmatically, so the tableviewcell is the delegate/datasource for collectionview.
My datasource structure, is an array of arrays.
My tableview, has, for every tableviewcell, a tableview section.Tableview datasource methods work without problem using the array. I am able to set up the tableview correctly.
Inside this cell, i want to display a collectionview, with horizontal scrolling.
The problem which i am encountering is i cannot assign datasource correctly using the arrays to collectionview. What happens is when i load the tableview, and scrolling down, i see duplicate records, so for example the first 3 rows are displayed correctly(in terms of data and number of items),but from the 4th row, for example, data is duplicated, so i see again the records for the first 3 rows, and of course this does not have to happen, because if i scroll on the 4th line(the collectionview on the 4th row) the app crashes due to an index problem out of range.
This is simple to understand: lets say i have 10 cells on the first row, and 5 on the 4th row/or section, as you prefer... Scrolling the 4th row'scollection view will cause the crash. This is because of the wrong data which is actually the same from the first row: instead, i have only 5 cells to render...
Tecnique i am using is pretty simple: give each tableviewcell's tag the actual indexpath.section. Then in the collectionview, use this tag to loop through array and then the indexpath.item to get the correct array.
Lets get a look into the code now:
Tableview
func numberOfSections(in tableView: UITableView) -> Int {
return DataManager.shared.datasource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! DiarioTableViewCell
cell.tag = indexPath.section
return cell
}
TableviewCell
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: "cell")
collectionView.register(DiarioCVCell.self, forCellWithReuseIdentifier: "cellCV")
collectionView.delegate = self
collectionView.dataSource = self
DataManager.shared.istanzaCV = self.collectionView
addSubview(tableCellBG)
addSubview(collectionView)
setConstraints()
}
CollectionView
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let tvCell = collectionView.superview as! DiarioTableViewCell
return DataManager.shared.datasource[tvCell.tag].count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellCV", for: indexPath) as! DiarioCVCell
let celltag = (collectionView.superview as! DiarioTableViewCell).tag
cell.datasource = DataManager.shared.datasource[celltag][indexPath.item]
return cell
}
Notice i have read all the possibly related threads, even ashfurrow's article, and here on stack, but i was not able to find a solution.
Thanks for any help!
Try to reload your collection view when cell is showing. Cells are being reused to save memory so they are created only once - you are setting all data at init and it's staying there forever.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! DiarioTableViewCell
cell.tag = indexPath.section
cell.collectionView.reloadData()
cell.collectionView.collectionViewLayout.invalidateLayout() //just to be sure, maybe it's not necessary
return cell
}

UITableViewCells invisible

Requirement :
I have a list of UITableviewCell loaded from a nib that I'm presenting on UITableview. The first time I open the UIViewController all cells are shown correctly and work as expected.
Issue :
If I navigate back to the parent and then open the UIViewController again the UITableviewCell are 'invisible'. I say invisible because with a breakpoint in cellForRowAt I can see that the table view does load all cells and the cells are valid.
Code :
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 13
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = (project?.sliderData.sliders[indexPath.row].view)! as UITableViewCell
print(cell.contentView.subviews.count)
if let left = cell.viewWithTag(2) as? UILabel {
left.text = "left"
}
if let middle = cell.viewWithTag(3) as? UILabel {
middle.text = "middle"
}
if let right = cell.viewWithTag(4) as? UILabel {
right.text = "right"
}
return cell
}
Screen Shot Image
Expected observation :
I was thinking that maybe the subviews of the cells get released because I don't have any bindings to them in IB. To test this I'm printing the count of subviews and writing some text to the subview labels. And everything seems to go fine, the cells are loaded and the labels are there but the cells just don't show up.
But then, if I scroll the TableView up and down a little to get some cells updated those cells do appear at the top and bottom of the view as shown in the pic.
You need to call dequeueReusableCell(withIdentifier: "cell") inside your code then will show your table cell. It will reuse cell for your all numbers of row data content.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! UITableViewCell
return cell
}
More Details : How to create uitableview with multiple sections in iOS Swift.
Did not find reason why the tableView behaves the way it does so I solved the issue by dequeueing default cells. The views provided by the slider objects are added as subviews to the dequeued cells. Now the subviews can of course be any UIViews.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "sliderCell")
if cell == nil {
cell = UITableViewCell.init(style: .default, reuseIdentifier: "sliderCell")
}
cell?.addSubview((project?.sliderData.sliders[indexPath.row].view)!)
return cell!
}

iOS - UITableView add single static cell to dynamic table

I Have a UITableView which is controlled by NSFetchedResultsController. I want to add single cell to the first row and make this cell static. In other words, there will be a button which will open another View Controller.
Until now, I was ok with fetched results controller and table. Now I'm a bit confused. How should I do this?
Instead using a header might be ok too, but I don't want this header to be on top all the time. I want this cell to be just like WhatsApp iOS "Create new group" cell on chats panel.
Thank you!
var dataArray = ["A","B","C"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArray.count+1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "CreateNewGroupCell") as! CreateNewGroupCell
return cell
}
else
{
// Get the data from Array
let data = self.dataArray[indexPath.row-1]
// Logic to show other cells
let cell = tableView.dequeueReusableCell(withIdentifier: "OtherCell") as! OtherCell
return cell
// ....
}
}
You will need to create tableview with number of rows fetched from NSFetchedResultsController +1. Also in cellForRowIndex method you will need to add a check like indexPath.row == 0 and in there you will make the changes.
Also you will have to add action for that button within that section. You can also set different custom tableview for first row.
It can be similar to following:
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row==0){
let cell = tableView.dequeueReusableCell(withIdentifier: "CellWithButton", for: indexPath) as! CellWithButton
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "OtherCells", for: indexPath) as! OtherCells
//here add data for cells from your array
}
return cell
}

Resources