In my table view, I have three sections, of which the first section contains a image cell, the second section contains segment control cell, and the third section contains some label cells.
What I am doing is when the user scrolls up the table view, everything will scroll up but the position of the segment control cell will be fixed at the upper margin of the screen.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSIndexPath *indexPathOfCurrentHeaderCell = [NSIndexPath indexPathForRow:0 inSection:0] ;
UITableViewCell *headerCell = [self.tableView cellForRowAtIndexPath:indexPathOfCurrentHeaderCell];
if (headerCell.frame.origin.y < self.tableView.contentOffset.y)
{
self.cellHead.hidden = NO;
self.cellHead.frame = CGRectMake(0, self.tableView.contentOffset.y, self.cellHead.frame.size.width, self.cellHead.frame.size.height);
}
[self.tableView bringSubviewToFront:self.cellHead];
}
But the function bringSubviewToFront: does not seem to work here (the second section will be covered by the third section). I think it is because the cells are not the subviews of the table view.
What can I do if I want to pull the segment control cell to the front?
You should add the segment control as a header instead of a cell in the tableview, using
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
then, you would have 2 sections,
1. image cell
2. segment control as header, labels as the cells
Related
I try to make cells expand/collapse with drop-down like animation, so when table view recalculates height it moves down other cells below the one that was tapped,
but if the tapped cell top margin is not entirely visible, table view changes its height update behavior by moving all above cells up:
http://imgur.com/CldzuFf
Is there a way to make cells expand with top-to-bottom behavior always?
Reloading cells like this:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:arrayToReload withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
Just set the contentOffset based on selected row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * theCell = (UITableViewCell *)[tableView
cellForRowAtIndexPath:indexPath];
CGPoint tableViewCenter = [tableView contentOffset];
tableViewCenter.y += myTable.frame.size.height/2;
[tableView setContentOffset:CGPointMake(0,theCell.center.y-65) animated:YES]; // need to customize the y offset 65 to your value
// reload row here
}
Using the willDisplayCell method I got the index of the last visible cell:
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
indexVisibleCell = [indexPath indexAtPosition:[indexPath length] - 1];
}
where indexVisibleCell is an NSUInteger that is declared in the class' interface. My problem is that I want to shift only one cell when user taps on the right or left button. I have applied this code for that purpose:
- (IBAction)rightButton:(id)sender {
NSUInteger indexOfScrolledCell;
indexOfScrolledCell = indexVisibleCell;
if (indexVisibleCell < 9) {
NSIndexPath *path = [NSIndexPath indexPathForRow:indexOfScrolledCell+1 inSection:0];
[self.obj_CollectionView1 scrollToItemAtIndexPath:path atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
}
as I show 3 cells at a time. By using that rightButton action method it shifts 3 cells at a time, not one. Please help me figure out how to scroll one cell at time.
Try using UICollectionView with paging enabled. Use following code, hopefully it works out for you.
[yourCollectionView setPagingEnabled:YES];
Use visibleCells to get your visible Cells, get the leftmost Cell index to figure out the next index, then scroll to that Cell on the left (similar logic to your code).
willDisplayCell is not reliable since it is called both times when you scroll left/right, and you're thinking that index is the left/right most is not correct.
Edit:
Or you need to compare the index in willDisplayCell correctly, to get the correct left/right most index, based on your logic.
For right button you can use following
[self.obj_CollectionView1 scrollToItemAtIndexPath:path atScrollPosition:UICollectionViewScrollPositionRight animated:YES];
and for left button following
[self.obj_CollectionView1 scrollToItemAtIndexPath:path atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
I am changing UICollectionViewScrollPosition so that when you scroll to right new item shows up on right side of collection view and when you scroll to left new item shows on left side of collection view.
I've implemented a UITableView that has section headers above each section. I've designed the table with the Grouped style so the headers scroll with the table instead of fixing to the top. I have also added a section index so users can tap/swipe to jump to a specific section. The problem is doing so jumps to that section but it shows the section header at the top. In this case that's undesirable - I want to scroll so the very top of the first cell is at the top of the screen, with that section header not visible.
How can you scroll just past the section header when the user taps an icon in the section index for UITableView?
Just try this
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 section:desiredSectionIndex];
[tableView scrollToRowAtIndexPath: indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
Found a solution. Perhaps there is a cleaner solution but this is working well for me.
Return -1 to prevent the table view from scrolling to any section when that method is called. Just before the return, add the logic to scroll to the desired location by getting and modifying the frame of the next cell.
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
CGRect nextRowRect = [tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:index]];
nextRowRect.origin.y -= tableView.rowHeight;
nextRowRect.size.height += tableView.frame.size.height - tableView.contentInset.top - tableView.contentInset.bottom - tableView.rowHeight;
[tableView scrollRectToVisible:nextRowRect animated:NO];
return -1; //prevent auto scroll
}
I have a UITableView with custom cells in it. The cells expands when I tap on them. I am facing an issue when I tap on the cell which is half cut by the bottom screen edge of the device. When I tap on this cell, I want cell to move up and then expand to show the details but right now it just expands and I do not know if is expanded or not. I need to manually scroll the table view up to see it.
Below is my cell tapping code. I implemented the related cell expansion methods and cell is expanding properly.
- (void)cartTableView:(UITableView *)iTableView didSelectRowAtIndexPath:(NSIndexPath *)iIndexPath {
[self.temporaryCartTable scrollToRowAtIndexPath:iIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
[self expandOrCollapseCartCellAtIndex:iIndexPath];
}
- (void)expandOrCollapseCartCellAtIndex:(NSIndexPath *)iIndexPath {
self.selectedIndexPath = iIndexPath;
[self.temporaryCartTable beginUpdates];
[self.temporaryCartTable reloadRowsAtIndexPaths:#[iIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.temporaryCartTable endUpdates];
}
After expanding, call scrollToRowAtIndexPath, which should position your cell correctly.
You need to check if rect of the cell you're extending (rectForRowAtIndexPath:) is fully within the bounds of the table view (based on contentSize and contentOffset, using CGRectContainsRect and if it's not - and only partially visible - then you need to scroll it to the bottom/top of the table view.
I have a UITableView with Dynamic Prototypes.
I implemented the code below so that when I select a row, it will be marked and the previously selected row will be unmarked.
However, for example, the row I selected is displayed in the middle of the screen, then when I scroll up or down, another cell (which is in the same middle position of the screen) is marked. In short, every view, there is a selected cell at the middle.
Please advise.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *oldIndexPath = [self.tableView indexPathForSelectedRow];
[self.tableView cellForRowAtIndexPath:oldIndexPath].accessoryType = UITableViewCellAccessoryNone;
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
return indexPath;
}
Probably you are overwriting accessoryType in your cellForRowAtIndexPath method - this is called each time table is about to draw new rows which were invisible before (as you described when you scroll up / down).
You need to handle it also in that function and update accessoryType there - otherwise it will randomly reuse a cells with different accessoryTypes.
You are modifying just the visuals of cell, you're not updating the data model. Store the selected index path in a #property somewhere, and adjust accessoryType inside cellForRowAtIndexPath.