I have the following code
if(self.roCount < 4)
{
[self.tableView scrollRectToVisible:CGRectMake(0, 50, 1, 1) animated:NO];
}
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
I need the tableview to scroll BEFORE it tries to delete the row. This is because if I get down to the last 4 rows, trying to delete it throws an exception relating to the animation not having enough room to animate due to the header I have in place.
If I change this code to scroll when self.roCount is higher so I can see if it even works, it scrolls, but not until AFTER the cell has been deleted. Shouldn't it scroll BEFORE it tries to delete the cell? Why do I not see the scroll happening until after the cell has been deleted?
When you call scrollRectToVisible: with animated set to NO, that executes immediately, but does show up on screen until the next display cycle.
To get the effect you want, you should probably scroll with animation, then after that animation completes, delete the rows.
Related
i have created ios app. uitableview each row show on textbox. button click to move next row. default show on 10 rows. last record to scroll to another records.
here is the code
if (![self.tableView.indexPathsForVisibleRows containsObject:indexPath]) {
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition: UITableViewScrollPositionMiddle animated:YES];
self.nextRow = i;
self.nextColumn = j;
}
now scroll the table but cursor focus on last records(10). how to focus set on 11th records. here is the attachment
Try TPKeyboardAvoidingTableView class for your tableView. It will manage this by itself.
We have a UITableViewCell with a list of rows that work like an accordion list.
When a user clicks on an accordion tableview cell, it will expand the tableview and is meant to push the cell right to the top, regardless of which one it is.
We use:
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]
This will scroll a cell to the top, and it works for the first few cells, but the closer you get to the bottom the less likely a UITableViewCell will bubble up to the top of the view.
The very last 2 or 3 cells will not go to the top of the tableview.
I believe this is a content inset issue and have tried;
myTableView.contentOffset = CGPointZero;
I have also tried
[tableView scrollRectToVisible:CGRectMake(0, 0, tappedCell.bounds.size.width, tappedCell.bounds.size.height) animated:YES];
But these do not make the bottom few cells bubble to the top.
I am wondering, is it possible to force a given UITableViewCell to the top of the tableview, and make sure the content offset forces padding underneath it to ensure it has the padding to force it to fill the entire tableview area.
Thanks now.
UITableView's content height equals to total height of all the cells it contains. UITableView inherits UIScrollView and scrolling is limited by its content size. You can try to set table's content size explicitly via it's contentSize property, e.g:
tableView.contentSize = CGSizeMake(tableView.frame.size.width, cellsCount * cellHeight + someNumber);).
If that doesn't help then you can change table's contentInset, e.g:
tableView.contentInset = UIEdgeInset(0, 0, someNumber, 0);
I am using setContentOffset on a UITableView because I want to initially hide a search field that is my tableHeaderView.
[self.tableView setContentOffset:CGPointMake(0, 56)]; // No scroll please!
Each time I push a new viewController I want to hide the search bar with contentOffset. But when I pop a viewController that offset is no longer in effect for some reason and shows the search bar. Why is this?
you can try and implement it on the following
- (void)viewWillAppear:(BOOL)animated {
[self.tableView setContentOffset:CGPointMake(0, 56)];
}
that will put the table in the correct position before it is displayed on the screen, I am assuming you mean no animation while setting the position.
I am guessing that you want to stop the user being able to scroll to the very top of the screen. If so you can implement the following UITableView delegate (on iOS5 and above):
scrollViewWillEndDragging:withVelocity:targetContentOffset:
which allows you to modify the final target for a change in the contentOffset. In the implementation you do:
- (void)scrollViewWillEndDragging:(UIScrollView *)theScrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
if(targetContentOffset->y < 56) {
targetContentOffset->y=56;
}
}
If you are trying to preserve the value of something during an action that loses it, the natural solution is to hold onto it yourself ("Hold/Restore"):
"Hold": get content offset to a field or local variable. Apple doc
.. do whatever you want.
"Restore": set content offset to the value you got above.
(Sorry, I don't write Objective C code, so can't provide the exact code. An edit to add the code, would be welcome.)
In a different situation, it might be necessary to hold the row you were at, and then scroll back to that row:
(Adapted from: https://stackoverflow.com/a/34270078/199364)
(Swift)
1. Hold current row.
let holdIndexPath = tableView.indexPathForSelectedRow()
.. do whatever (perhaps ending with "reloadData").
Restore held row:
// The next line is to make sure the row object exists.
tableView.reloadRowsAtIndexPaths([holdIndexPath], withRowAnimation: .None)
tableView.scrollToRowAtIndexPath(holdIndexPath, atScrollPosition: atScrollPosition, animated: true)
I am trying to update a custom tableview cell's progressview but the progress view wont update.
I can set the labels on the tableview cell but accessing things like progress bars or activity indicators doesnt work.
I do the following on the custom cell
cell.progressView.hidden = NO;
cell.progressView.progress = 0.5;
[cell.progressView setNeedsDisplay];
This doesnt work even though in the debugger I see the object is of the correct cell type and the progressView is allocated.
I have tried setNeedsDisplay on the cell itself as well, but no luck. What am I missing?
Calling [self tableView:tableView cellForRowAtIndexPath:indexPath]; is most likely the problem because this likely results in another cell being dequeued from the table. So you end up setting up a new cell, not the one currently being display.
Instead, do this:
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
This directly asks the table for the cell. This should return the currently displayed cell if the row is visible.
I'm having a hard time understanding some of the logic behind the UITableView. I am populating my table from a MPMediaItemCollection as a queue of songs. What I am trying to achieve is to have a now playing indicator as the accessory view of the cell at the index path that matches the currently playing song.
I originally tried this with the following:
if (indexPath.row == [mutArray indexOfObject:[mainViewController.musicPlayer.nowPlayingItem valueForProperty:MPMediaItemPropertyTitle]]) {
UIImageView *playButtonView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"PlayButton.png"]];
[cell setAccessoryView:playButtonView];
}
This works fine for the now playing item, which is always actually objectAtIndex:0. But what I don't understand is why my table seems to define this index once every height of combined visible cells.
Let me try to explain this more clearly. Lets say that my table is 600px tall, and its content height is 1800px. This causes the indicator to be added roughly every 600px down the content height.
Now my first thought was that this was something wrong with the code for judging the index based off the name of the song, so I tried changing it to:
if (indexPath.row == 0)
But this produces the same result!
This screenshot should help explain what I'm talking about.
So, is there anything I can do to make the table treat indexPath0 as only the first cell in reference to the entire table instead of in reference to the currently visible cells?
You have to state explicitly also when the accessory should not be there:
if (indexPath.row==0) {
UIImageView *playButtonView = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:#"PlayButton.png"]];
[cell setAccessoryView:playButtonView];
}
else {
[cell setAccessoryView:nil];
}
The reason is that when cell 0 gets dequeued (i.e. reused) on a different row it still has the accessory view in it.
Actually, this is a nice case study for understanding how dequeueing table view cells actually works ;-).
That's how tableview reuse cells: when cell scrolls out of screen it's added to reuse pool, so once you've added your accessory view to cell and that cell is reused - you'll see it in random places while scrolling.
You can check your cells index in -willDisplayCell:forIndexPath and add (if it's not added), hide (if it's there, but not your desired index) or show (if it's there and it's your index), or add accessory view to all cells and show/hide as needed.