I have a UITableView with a play icon in each cell. When you tap on that play icon it changes to a "Pause" icon. That works marvellously, but if you tap on an icon in another cell, how do I notify the previous cell to change back into a "play" icon? Basically I think I need a way to notify all the UIImage views inside cells at once. All of them for the whole table
You should have a var for playing indexPath.
When tap on another cell:
For visible cell: checking in array of visible cells with playing indexPath. -> if indexPath is in visible cell change 'pause' to 'play'
Then -> assign playing indexPath to current cell.
For unloaded cell: check it in cellForRowAtIndex. if indexPath != playingIndexPath -> 'play'
Sorry, I can't write ios code because you didn't show any. Hope this help
Three simple steps which you need to do in the sequence
1.In tableView:cellForRowAtIndexPath: datasource method, set the default image of the imageView as 'play'.
2.When the imageView of any cell is tapped, call the tableView reloadData method, which will reload the imageView of all cells to the default image.
3.Now change the imageView of the tapped cell to 'pause'.
As the second step sets the imageView of other cells to default, no separate notification is required. Happy coding :)
Related
I have a table view full of songs, each cell has a Play button. Once you press the Play button the song plays and the Play button in the individual cell turns to a Stop button. Now this cell was done using View Tags, so when you scroll down further and as cells are reused, random cells that come into the view have a Stop button even though they were never selected. What is the best way to prevent this reuse from happening? Should I refactor my code into a custom UITableViewCell class and prevent reuse on the button? Or is there a quicker work around here?
You should remember playing state for song and update button status when reusing the cell (the same way you're updating other properties like title, artist etc).
For example, you can save playing song index in controller private variable (initially set it to -1) and compare it to indexPath.row when reusing the cell.
I am able to detect when a cell is removed from the UITableView by writing a handler for the method tableView:didEndDisplayingCell:forRowAtIndexPath:. This method is called whenever a cell is removed from the display. However, there is one exception.
When the cell has a UITextField and the field is the first responder, this method is never called even when it's scrolled off the display and the cells immediately before it and after it are.
The cell is also confirmed to be removed from the UITableView with a test while the cell is scrolled off the screen. The call to cellForRowAtIndexPath: returns nil under this condition.
I also subclassed the UITableViewCell and wrote a handler for removeFromSuperView. Again this method is called for all the cells when the are scrolled off the screen except when the cell has a UITextField and it is the first responder.
Another thing to note is that the UITextField in the cell accepts key input while it is scrolled off the screen and the call to cellForRowAtIndexPath: returns nil. I can see this when the cell is scrolled back into view.
Does anyone have any solutions for detecting when the cell is scrolled out of view, so that the controller can get access to the UITextField?
You could try to resign your first responder manually before the cell disappears. Depending on your requirements, this could be done in multiple ways, usually when the user starts scrolling. You could restore the first responder after he finishes scrolling, if the cell is still visible. Probably better from the graphical design point of view as well.
Alternatively, you could try to implement delegate's tableView:willDisplayCell:forRowAtIndexPath: and make a previous visible cells set, which you'd intersect with tableview's visibleCells array. The elements that are not in the current visibleCells but are in the previous were removed. Then assign a copy of visibleCells to previousVisibleCells.
This is probably a bug in Apple's code, you could file a radar for it.
I have set a UICollectionView to 'Paging Enabled'. I want to be informed when a UICollectionViewCell becomes active.
It seems like the collectionView:didSelectItemAtIndexPath: of the UICollectionViewController cannot achieve this effect: It only fires when a user explicitly select a cell, not when the cell is swiped to the front.
Each cell has a view controller associated with it. I probably can use viewDidLoad to as a proxy of this event. But it does not sound like a clean solution.
You can use collectionView:didEndDisplayingCell:forItemAtIndexPath: to detect that something changed and visibleCells to know what now on screen
I have a Static TableViewCells on a storyboard. There are just labels in those cells. I would like to fire IBAction event upon touch. What I am doing right now is create a full-size white button and linked to IBAction. But it doesn't show highlighted color when the cell is selected because cell is behind the button.
UITableViewCells have a delegate method specifically for handling row touches -tableView:didSelectRowAtIndexPath:
If you need a custom button over each cell, subclass UITableViewCell instead of going through a storyboard. As much as they may be a timesaver, storyboards are really a limiting factor when it comes to nitty gritty iOS programming.
Try adding this in your cellForRowAtIndexPath (when you initialize each cell):
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
Does this fix it?
I've got a custom UITableViewCell that has a label and a UIPickerView. Display works fine, but when I want to select a value in the Picker, the TableView scrolls. What can I do so that the gestures in the cell go to the Picker instead of the whole TableView?
The only solution I could come up with was to set the whole TableView to scrollEnabled = NO. This works for the Picker, but now I can't get to the cells under the custom cell. Control has to be more fine-grained.
If you can get hold of the UIGestureRecognizer for each of the two gestures, and tell one it needs to wait for the other to fail. With one in every cell, that becomes over-wieldy.
Perhaps you should add a control or have the accessory view "bring up" the picker, and then dismiss it when done.