I need to add a table view in a specific are of my screen which is inside another UIView. When the user press a button the table view is created and displayed perfectly fine. However I need to know the user selection so I create it in the following way:
self.dynamicTableView = UITableView(frame: self.viewForTableView.bounds)
self.dynamicTableView?.dataSource = self
self.dynamicTableView?.delegate = self
self.messageZone.addSubview(self.dynamicTableView!)
self.dynamicTableView?.reloadData()
The data sources methods are being called but the delegate is not, so the following println is not working
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Hello")
}
As additional information I'm using a custom table view cell
UPDATE: I just discover that if I implement shouldHighlightRowAtIndexPath sometimes if I do a long press it works, like if I keep the cell pressed for about four seconds, but not always, just some times. Can it be any view that is behind the table view what is causing this weird behaviour?
Related
I have made a TvOS app which has 2 collection views they will be scrollable horizontally.
Now both of them have items which open corresponding cell's detail page.
That new page is pushed on navigation stack, when I come back I want my focus to remain on same cell of the collection view which opened the new page.
So, I found and tried two methods.
Method 1:
Setting collectionView.remembersLastFocusedIndexPath = true for both collection views
Method 2:
Using indexPathForPreferredFocusedView(in:) in delegate of both collection views.
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// SOME WORK
focusedCellIndexPath = indexPath
}
override func indexPathForPreferredFocusedView(in collectionView: UICollectionView) -> IndexPath? {
return focusedCellIndexPath
}
Now when I used Method 1:
Say I have 10 cells in both collection view.
I was on cell 2 in first collection view, then I press down and scroll till the end on the second collection view and I press up then I go back to second cell of first collection view.
But when I used Mewthod 2:
When I press up then I don't go on second cell of first collection view but go on the cell just above currently focused cell of second collection view.
I want to know why they both behaved differently, looking at official documentation of method used in method2 in its discussion section it looks both things should behave similarly, but that is not the case here.
I want to implement pull to refresh effect but on UITableView bottom using UIRefreshControl ?
Any ideas?
It is not possible to put UIRefreshControll to bottom of UITableView in a manner similar to putting it to top. But anyway, you're able to place everything on table view's background view.
But the solution which I prefer is to download additional items when user scrolls to the most bottom of table view. I handle it via UITableViewControllerDelegate method:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == self.items.count - 1 {
// Download more items
}
}
These are the two things i typically do:
Configure a Footer View which displays the loading Indicator.
Provide a additional cell from the TableViews or CollectionViews
Datasource which presents a loading indicator. Depending on the current loading state it could display a label like "No more items available" or the actual Indicator
I have a table view with a few different prototype cells. I want to have one prototype cell segued to one controller and the rest should not be clickable i.e. no seg.
Right now, I have one button linked to a controller successfully but when I tap on the tableview prototype cell which is segued to a different controller (in the storyboard) nothing happens. I don't get any error either.
What is the best way to go around this? Can I make two different segues in the storyboard? Or do I need to implement something in the tableview method did select row at index path, somehow grab the class associated with the row clicked and programmatically segue to a different screen? Something like:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("here")
//self.performSegueWithIdentifier("profileSeg", sender: self)
}
I am not getting the println here when I select a cell and yes I have assigned the delegate in viewdidload.
EDIT
I've just realised I made a mistake when explaining the question. I actually have a view at the bottom which links to one view controller. It is not a tableview row... This is the seg that works. But I have ctrl dragged to from one type of cell to a second controlleR and that seg is not working. There are also 3 other types of cells none of which have segs attached. Is this anything to do with the issue?
If didSelectRowAtIndexPath not working, it can be caused by either your UITableViewDelegate has not been set, or, it might possible that Selection of your UITableView has been turned off, need to Turn on, see image to find how.
Cheers.
Don't segue directly from cell to 'ViewController', you must segue cell 'ViewController' to the other 'ViewController'. You can segue many times from 'ViewController'.
And please add this code
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
if indexPath.row == 0{
performSegueWithIdentifier("profileSeg", sender: self)
}else{
performSegueWithIdentifier("anySeg", sender: self)
}
}
There are two ways to do what you want:
First if you only want to link ONE TVCell with one ViewController you could do what you started to do: Link every TVCell with the ViewController you want to go from there. For that hold ctrl and drag and drop from the prototype to the ViewController. So every TVCellPrototype can have one segue and if you hit the cell it will automatically perform the segue.
This is also the reason why your code don't prints "profile seg".
In this case you don't need to give the segue an identifier.
The second way is better if you need to have MULTIPLE segues from one TVCell to 2 or more ViewControllers. For this you link the ViewController of the TVCells with the ViewControllers you want to go. That way you can set as many segues as you want but you have to give them an identifier because you have to call them in the tableView(... didSelectRowAtIndexPath) function. (click on the segue in interface builder to give it an identifier). This will look like:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("ProfileSeg", sender: AnyObject?())
}
Now lets talk about why you don't get the println("here"):
There has to be a mistake according the function because there is no "override" in front of it. In general the compiler won't build your App because it is missing. I don't have all the code so i can't exactly say whats your mistake.
I have a uiviewcontroller with a container on it, embedded inside of that is a uitableviewcontroller that has static cells and static content. When I tap the cell "Trip Info" it segues to the Trip Info View Controller. When coming back the static cell is highlighted.
I have seen many posts saying to add code to the didselectrow tableview method but I dont use one because my content is static. Any ideas?
Okay, just because you have static content doesn't mean you get to skip using the tableview delegate. It's not hard to set up.
tableView.deselectRowAtIndexPath(index)
There's not another way.
I ended up figuring it out on my own.
You need to make a swift file for that UITableViewController that is embedded into the UIViewController.
Then make sure your tableview is a delegate, and then call the
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
in that new file you created.
I am making an iOS app that relies on a table view. In each cell of the table view, there are 4 buttons aligned on the bottom. I have a cell class that is pretty standard and a feedController to handle the table and setting all the items of the cell.
Everything works fine on it but I can not figure out how to handle the button clicks within the cell. I can hard code it into my cell class, but then every 3 cells has the same interaction. Is there a way to pass the button click function from the cell class into the controller? I have tried checking the state from the controller and that has not worked.
Can you add a gesture recognizer as you're doing your cellForItemAtIndexPath? So I had something similar with a collection view, and what I did was as it within:
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as MyCollectionView
...
I would add a gesture recognizer to each cell
i.e.
cell.addGestureRecognizer(UITapGestureRecognizer(target: self, action:Selector("tapAction:")))
And then something like:
func tapAction(recognizer: UITapGestureRecognizer) {
...
}
so recognizer ends up being the specific item tapped, and I could take action accordingly (in my case, I had my datasource of items and I would find the item in an array by casting recognizer to a cell, finding the appropriate subview, and update values on it)
I would add code block properties to your cell class which the table can assign to deal with each button. In your cell, code each button handler to call the appropriate block, or pass an index for the button used in a single block.
See my answer here which has an example, but for a switch.
How can I get index path of cell on switch change event in section based table view
If after a few cells you get the same interaction, it's possibly because you're dequeueing a reusable cell, and you're getting the same cell.
Make sure to set your .setTarget() call for your buttons in your tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) data source every time the cell is dequeued. It would help if you shared how you're handling dequeuing to see if this is your issue.