I would like to know if there is a way to detect if the current UITableViewCell is the last one in view then when the user pressed enter you will scroll the UITableView using this code
int cellHeight = 44;
[finishingTableView setContentOffset:CGPointMake(finishingTableView.contentOffset.x,finishingTableView.contentOffset.y + cellHeight) animated:YES];
I have a UITableView with custom UITableViewCells, each UItableViewCell has a UITextfield and I am programmatically selecting the UITableViewCell then making the cells textfield become first responder. I want to allow the user to hit enter all the way to the bottom of the UITableView but only start scrolling when the next UITableViewCell to select is out of view.
Use the indexPathsForVisibleRows method of UITableView.
NSArray *visibleRows = [self.tableView indexPathsForVisibleRows];
NSIndexPath *lastRow = [visibleRows lastObject];
Then compare that to the indexPath you have for the cell you are dealing with.
Related
I am creating a Chinese learning app, with a section for correctly pronouncing certain sounds. To organise these sounds into a table, I have created a UICollectionView, where each UICollectionViewCell contains a UITableView.
Each UICollectionViewCell acts as a column, and contains a UITableView.
Each UITableViewCell acts as a row in each column.
This results in the following appearance.
However, although I can easily detect taps on each UICollectionViewCell using collectionView:didSelectItemAtIndexPath: , I am unable to detect any touches at all on the UITableViewCells within.
Whether I convert the view in the Cell to be a button, or whether I as a UITapGestureRecognizer, or whether I use the function tableView:didSelectItemAtIndexPath, no touches at all are detected in the UITableView.
How can I allow my code to correctly detect these touches on the UITableViewCells within the UICollectionView?
Thanks!
Update 1:
Here is the #interfact of the Column .h file (UICollectionViewCell)
#interface PronounciationColumn : UICollectionViewCell <UITableViewDelegate, UITableViewDataSource>
In the .m of the UICollectionViewCell, the delegate and dataSource of the tableView is set to self.
Update 2:
Another user had a really neat idea of setting the delegate of the tableView to it's own collectionViewCell using the following code:
- (PronounciationColumn *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
PronounciationColumn *column;
NSString *columnIdentifier = [self getIdentifier:collectionView];
if (column == nil) {
column = (PronounciationColumn *)[collectionView dequeueReusableCellWithReuseIdentifier:columnIdentifier forIndexPath:indexPath];
column.arrayOfFinals = [[self getArrayOfPinyins:collectionView] objectAtIndex:indexPath.item];
}
column.tableOfFinals.delegate = column;
column.tableOfFinals.dataSource = column;
return column;
}
The tableView continues to be populated correctly, however, the touches are still not detected on the cells, as tableView:didSelectRowAtIndexPath: is still not called.
I have a UICollectionView with 1 row 1 column. I want to get the first item (indexPath basically) when I am scrolling it horizontally.
For example, I have got 100 items displayed horizontally in my UICollectionView and when I scroll from right to left, whichever item is the first one visible, I need its indexPath.
Which means the indexPath will be constantly changing while its scrolling.
How to achieve this? Please Guide. Thanks!
collectionView.indexPathsForVisibleItems() returns an array of NSIndexPath for visible cells. You can get the left most one by sorting them by NSIndexPath.item.
Edti:
To be notified while scrolling, implement the UIScrollViewDelegate method scrollViewDidScroll(_: UIScrollView). Remember that UICollectionView is a subclass of UIScrollView.
I think you need implement UIScrollView delegate method and get visible cell inside
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
UICollectionViewCell *firstCell = [[collectionView visibleCells] firstObject];
NSIndexPath *firstIndexPath = [collectionView indexPathForCell: firstCell];
NSLog(#"%#", firstIndexPath);
}
Hope this help
I have a UITableViewCell which contains a UICollectionView. The UITableViewCell also contains a UIPageControl. I want to change the dots as the UICollectionView is swiped. I am using
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
to get the current visible UICollectionViewCell. But my problem is that since the UICollectionView lies in UITableViewCell to fetch the reference to the collectionView I require the indexPAth of the current table view in which collection cell is being swiped. How can I do this?
I want to do this:
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// Change the dots
CustomTableCell *tableCell = [self.currentTable cellForRowAtIndexPath:_tablecellIndex];
NSInteger currentIndex = tableCell.currentCollectionView.contentOffset.x / tableCell.currentCollectionView.frame.size.width;
tableCell.currentPageControl.currentPage = currentIndex;
}
But how do I get the _tablecellIndex?
I tried doing :
NSArray *indexes = [self.currentTable visibleCells];
_tablecellIndex = indexes[0];
But this is not always true as sometimes the table cells are displayed half and user is swiping second cell.
You need to ask the tableview itself, what indexpath a given cell has. You do that with this command :
[self.formTableView indexPathForCell:myCell];
The other problem in your case is that you are within the collection view on the cell, and not within the tableview itself. So theres a few ways to do that - one nice way is to set up a delegate on the cell that can access the tableview. Thats a bit involved, so heres an even simpler way (self in this case is the cell object):
UITableView *parentTableView = (UITableView*)self.superview;
NSIndexPath *cellIndexPath = [parentTableView indexPathForCell:self];
That should do the job.
I am using multiple UITableView with custom cells in a single viewController. Custom cell have textFields, I am able to edit the textFields. Now I want to get the tableViewCell of exact UITableView in the textField delegate method when am editing the textField ?
Remember there are multiple tableViews I want to get the exact cell of exact table which am editing. Any Help?
You must have tag to your both tableview
use below code in textfield delegate
UITableViewCell *cell = (UITableViewCell *) textField.superview.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
NEVER loop through superviews, the correct and most reliable way to do what you want is:
CGPoint textViewPosition = [textView convertPoint:CGPointZero toView:self.tableView];
CGRect senderFrame = CGRectMake(textViewPosition, textViewPosition, textView.frame.size.width, textView.frame.size.height);
NSArray *indexPaths = [self.tableView indexPathsForRowsInRect:senderFrame];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[indexPaths firstObject];
This may get more complex as you have different table views in 1 view, I suggest rethinking why you have more than 1 table view and see if you can't do this in a more efficient way i.e. 1 table view with custom sections etc...
I'm creating an app which contains a screen that shows a table view with custom cells. Each cell contains two labels and a subview, which further contains other subviews. I'm handling the click event on the cell to hide/show the subviews within the subview in the cell. How can I make it so that when I click on a single cell, the subview of all the cells will change?
It is like the Stock application in iPhone (using iOS 7), here is a screenshot:
As in the image above, when you click on any of the green box, all the boxes change to reflect the same type of value.
Please let me know if this approach is fine, or how this can be implemented.
There are a couple ways of doing this. The first that comes to mind would be to handle the different states within the UITableViewCell subclass, and just reload the visible cells:
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationAutomatic];
If you're looking for more control over the process though, this process could also be achieved by changing the state future cells should load into, and then calling a method on every visible cell. This would provide you with an easy way to have complete control over how the contents of the cell update.
// Change flag for cell state then...
for (NSIndexPath *indexPath in [self.tableView indexPathsForVisibleRows]) {
if (condition) {
MyCellSubclass *cell = (MyCellSubclass *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell someMethodWithArg:(id)state];
}
}
To do something as in Stock app you should handle two method cellForRowAtIndexPath: and click action method.
In cellForRowAtIndexPath: you should do the check which cell/button was pressed and display value base on it:
//Pseudo code
//cellForRowAtIndexPath
if (cellNo3Pressed)
{
//set up text with the right value.
}
else if (otherCell)
{
//set up text with the right value.
}
This will handle the cell which are not visible on the screen.
The next action method should handle nice animation on all of the visible cell:
NSArray *paths = [tableView indexPathsForVisibleRows];
for (NSIndexPath *path in paths)
{
UITableViewCell *cell = (UITableViewCell *)[self.tableView cellForRowAtIndexPath:path];
//Animate changes for cell
}