Position UITableViewCell on Top when Cell is selected - ios

I want that the selected cell will always be at the top most position of tableView.
I can to it via:
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
but my problem is, when the number of cells, for example, is just 3. When I select cell number 3, it just stays there. Was that the normal behaviour? If yes, then, can you suggest something so that I can achieve my goal? Thanks!

U can use contentInset and setContentOffset property of tableview for example
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = 44.0f;//cell height
tableView.contentInset = UIEdgeInsetsMake(0, 0, height * indexPath.row, 0);
//[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; //commenting u are setting it by using setContentOffset so dont use this
[tableView setContentOffset:CGPointMake(0, (indexPath.row * height) )animated:YES]; //set the selected cell to top
}
hope this helps u .. :)

You can use this code in the didSelectRowAtIndexPath delegate of table view
CGFloat height = 44.0f;//cell height
tableView.contentInset = UIEdgeInsetsMake(0, 0, height * indexPath.row, 0);
[tableView setContentOffset:CGPointMake(0, (indexPath.row * height) )animated:YES];

you can set UITableView content offset using
[tableView setContentOffset:offsetPoint animated:YES];
or
[tableView setContentOffset:offsetPoint];
and get your selected cell position by
CGPoint offsetPoint = [tableView cellForRowAtIndexPath:indexPath].frame.origin
then you can move cell to your desired offset as bellow
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
float topOffset = 64; //in case of navigationbar
CGPoint offsetPoint = CGPointMake(0, cell.frame.origin.y - topOffset);
[tableView setContentOffset:offsetPoint animated:YES];
}

Related

Keep expanded UITableViewCell fixed on top

I have implemented SKSTableView and I used this command:
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
when I press a cell that is expandable, and it goes on top. Now I'd like that when I scroll the expanded cell which went to top to stay fixed there until it's closed. Can I do that?
In UITableView you have the UIScrollView methods. So you can do something like this:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
UITableViewCell *cell =[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
CGRect cellFrame = [cell convertRect:cell.frame toView:self.view];
if (self.isStickToTop) {
self.cell.frame = CGRectMake(0, 0, self.cellFrame.width, cellFrame.size.height);
}
else {
self.cell.frame = CGRectMake(0, scrollView.contentOffset.y, self.cellFrame.width, cellFrame.size.height);
}
}
The isStickToTop is your maintenance BOOLvariable that will indicate if the cell stick to top or not. Don't say u don't know ;)

TableView Animation

I have a UITableView with some rows. I want the selected cell to always be at the top most position of UITableView and the cells after selected cell should animate to bottom.
For animating to top I used this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGFloat height = 44.0f; //cell height
tableView.contentInset = UIEdgeInsetsMake(0, 0, height * indexPath.row, 0);
[tableView setContentOffset:CGPointMake(0, (indexPath.row * height) )
animated:YES]; //set the selected cell to top
}
My problem is how can I animate cells after the selected cell to bottom?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
// I will assume you have your tableView's data stored in an array: _dataArray
[_tableView beginUpdates];
[_dataArray insertObject:[_dataArray objectAtIndex:indexPath.row] atIndex:0];
[_dataArray removeObjectAtIndex:([_dataArray count]-1)];
[_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
}

get cell from indexPath for expand the row when clicked?

I know there is a method called [tableView cellForRowAtIndexPath:indexPath]; which we can use to get cell at given indexPath.But i want to expand row when the row tapped.using this code-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// Toggle 'selected' state
BOOL isSelected = ![self cellIsSelected:indexPath];
// Store cell 'selected' state keyed on indexPath
NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
int sec = indexPath.section;
int row = indexPath.row;
NSString* indexpathStr = [NSString stringWithFormat:#"%d-%d", sec, row];
[selectedIndexes setObject:selectedIndex forKey:indexpathStr];
// This is where magic happens...
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = 0.0;
if([self cellIsSelected:indexPath]) {
//problem here
CalEventCell* cell = (CalEventCell*)[tableView cellForRowAtIndexPath:indexPath];
[self setDescriptionFrame:cell.descriptionLbl];
height = cell.descriptionLbl.frame.size.height+cell.eventLbl.frame.size.height +20;
}
else
height = 60;
return height;
}
when a row tapped i call beginUpdates and endUpdates methods on tableview and change row height in heightForAtIndexPath method.The problem is that as you can see i call cellForAtIndexPath from heightForAtIndexPath and in cellForRow there is beginUpdates method call which turn into a call to heightForRow and this loop never ends and program crash with EXC-BAD-EXCEP.
So any other method to get cell from indexPath or any other way to do so? Any help would be appreciated.
Take an array to store the selected indices and then reload that tableview.
If you tap that cell height will expand and again if you will tap it will decrease its height.
Check out the below code.
// Add a mutable array to your class
NSMutableArray *selectedCellArray;
// Initialise it in `viewDidLoad`
-(void)viewDidLoad
{
[super viewDidLoad];
selectedCellArray = [[NSMutableArray alloc] init];
}
// Add selected indices in selectedCellArray
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
[tableView reloadData];
if (![selectedCellArray containsObject:indexPath])
[selectedCellArray addObject:indexPath];
else
[selectedCellArray removeObject:indexPath];
[tableView beginUpdates]; // Animate the height change
[tableView endUpdates];
}
// Write the UI Updation in HeightForRowAtIndexPath Method
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = 0.0;
if (selectedCellArray.count>0) {
if ([selectedCellArray containsObject:indexPath]) {
CalEventCell* cell = (CalEventCell*)[tableView cellForRowAtIndexPath:indexPath];
[self setDescriptionFrame:cell.descriptionLbl];
height = cell.descriptionLbl.frame.size.height+cell.eventLbl.frame.size.height+20;
return height;
}else{
height = 60.f;
return height;
}
}
return height;
}
Hope This Helps
You should call below lines of code on your didSelectRowAtIndexPath method
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:row inSection:sec]] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
When row will be reloaded cellForRowAtIndexPath:indexPath and heightForRowAtIndexPath methods will be called where u can expand cell's height
You can't use cellForRowAtIndexPath in heightForRowAtIndexPath if you are using reusable cells. You need to calculate the height in some other way. The simplest way that would likely work for you would be to keep a prototype cell in your class that you only use for sizing purposes.
Try this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[your_tableView reloadData];
}

setContentOffset not scrolling my UITableView

I am trying to scroll my UITableViewCell up one UITableViewCell position when the selected cell reaches the last position in the UITableView
I have the logic correct for identifying the last visible UItableViewCell of the UITableView. However the code to make the UITableView scroll up one position is not working. This is the code I have written.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cellSelectedBool = YES;
cell = (CustomFinishingCell *)[tableView cellForRowAtIndexPath:indexPath]; // error
[cell.widthTexField becomeFirstResponder];
// Gets an array of current visible cells in UITableView
NSArray *visibleCells = [tableView visibleCells];
NSLog(#"%#", visibleCells);
// get indexpath of last cell
UITableViewCell *lastCell = [visibleCells lastObject];
NSIndexPath *lastCellIndex = [finishingTableView indexPathForCell:lastCell];
// perform scroll when last visible cell is selected
if (indexPath.row == lastCellIndex.row) {
NSLog(#"BIGGER");
int cellHeight = 44;
[UIView animateWithDuration:.25 animations:^{
[finishingTableView setContentOffset:CGPointMake(finishingTableView.contentOffset.x,finishingTableView.contentOffset.y + cellHeight) animated:YES];
}];
}
you should use:
NSIndexPath *rowToSelect; // assume this exists and is set properly
UITableView *myTableView; // assume this exists
[myTableView selectRowAtIndexPath:rowToSelect animated:YES scrollPosition:UITableViewScrollPositionNone];
[myTableView scrollToRowAtIndexPath:rowToSelect atScrollPosition:UITableViewScrollPositionNone animated:YES];
if (indexPath.row == lastCellIndex.row) {
[finishingTableView scrollToRowAtIndexPath:indexPathatScrollPosition:
UITableViewScrollPositionNone animated:YES];
}

How can I get the height of a specific row in my UITableView

In my UITableView i've set different heights for different rows using the delegate method: tableView:heightForRowAtIndexPath:
Now given a NSIndexPath, I would like to get the height I've previously assigned for a specific row.
You can use this
CGRect frame = [tableView rectForRowAtIndexPath:indexPath];
NSLog(#"row height : %f", frame.size.height);
Using frame.size.height you can get height of particular row
Swift 3
let frame = tableView.rectForRow(at: indexPath)
print(frame.size.height)
Simplly Use
tableView:heightForRowAtIndexPath
method
int row = 1;
int section = 0;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
float height = [self tableView:tableView heightForRowAtIndexPath:indexPath];
Hope this wil help for you :)
-(CGFloat)getHeightAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == 0)
return 20.0;
else if(indexPath.row == 4)
return 40.0;
return 50.0; //Default
}
Call the above function in tableView:heightForRowAtIndexPath: as
return [self getHeightAtIndexPath:indexPath];
And you can use the same function on say button click action of a button inside a specific cell, with having button.tag=indexPath.row
-(IBAction)btnClick:(id)sender{
UIButton *btn=(UIButton *)sender;
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:btn.tag inSection:0];
CGFloat height=[self getHeightAtIndexPath:indexPath];
}
By using below code you can get the cell height from tableview
let height = super.tableView(tableView, heightForRowAt: indexPath)

Resources