What I'm trying to do is call selectRowAtIndexPath in my searchResultsTableView. I am doing this in my viewWillAppear so that the row gets selected after it comes back from another view controller. In this simple example, I'm just asking it to go to row 2. What happens is that it briefly selects row 2 and then the selection goes away. Any ideas?
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// just select row 2 as a test
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:0];
[self.searchController.searchResultsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self.searchController.searchResultsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
}
Thanks
Maybe you should call it in viewDidAppear:, so it's selected once the view is present, and not just before it's presented. The superclass of your controller might deselect all rows on viewDidAppear: (I'm not sure of that, though).
Also, I think you can do those two lines in just one:
[self.searchController.searchResultsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionTop];
Just go with viewDidLoad or viewDidAppear, and just use the single line told by EmilioPelaez.
Related
I'm bulding a celander application and i want the calender to get scrolled to the current month when started. i used custom cell for each month. the code that i found to make this happen from this website is this:
[self.bahraincld reloadData];
NSIndexPath *scrollto = [NSIndexPath indexPathForRow:2 inSection:1];
[self.bahraincld scrollToRowAtIndexPath:scrollto
atScrollPosition:UITableViewScrollPositionTop animated:YES];
I'm using it in the view did load. it's giving me a signal SIGABRT.
is this code correct? where should i use it if i want it to work whenever the user starts the calendar.
Thanks.
You better put this code into viewDidAppear, because your tableView haven't loaded the data yet, so the cells are not created. In your case SIGABRT, is because row number 2 is beyond bounds.
Here is what i did, hop it helps someone.
//in the view will appear reload your table.
-(void)viewWillAppear:(BOOL)animated
{
[self.yourtable reloadData];
}
//in the view did appear, value = defining which costume cell to move to.
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
int value = 5;
NSIndexPath *scrollto = [NSIndexPath indexPathForRow:value inSection:0];
[self.yourtable scrollToRowAtIndexPath:scrollto
atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
I am developing an Iphone application ,this contain a UITableview with 8 cells.I am implement an NSMutableArray for store each cells when the cell creation time ,but the tableview load time only provide the displayed cell store to the array.For avoid this issue i have autoscroll the table view and get the total cell for store to the array with the following code;
-(void)viewDidAppear:(BOOL)animated{
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[musicGenre count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
This is working perfectly.But now i want scroll this from bottom to top at the same time(load time) .How to implement this ?
Thanks in Advance.
Since UITableView inherits from UIScrollView you could use something like this:
- (void)viewDidAppear:(BOOL)animated{
[table setContentOffset:CGPointMake(0.0, table.contentSize.height - table.bounds.size.height)
animated:NO];
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[musicGenre count]-1 inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
}
EDIT:
If you want the initial move from top to bottm also animated simply use:
- (void)viewDidAppear:(BOOL)animated{
[table setContentOffset:CGPointMake(0.0, table.contentSize.height - table.bounds.size.height)
animated:YES];
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[musicGenre count]-1 inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
}
But please consider user experience - is that ammount of animation needed? Because users (especially if they will often use your app) dont like to loose time. Animation is great when it enhances user experience and doesn't cause a delay in workflow.
EDIT2: for scrolling to top (from current position) you can use:
[table setContentOffset:CGPointZero
animated:YES];
I have a UITableView which is added to a view as a subview. When selecting a row a new view will be present with pushViewController: and the user has the option to push a Back-button to go back to the UITableView but then the cell is still selected.
Is there a way to deselect this when the view appears?
I have read that I should use the following code but I can't get it working. No errors, no warnings, no nothing.
[tableProgram deselectRowAtIndexPath:[tableProgram indexPathForSelectedRow] animated:NO];
You should deselect the row in the didSelectRowAtIndextPath method of the delegate of your UITableView. It should look something like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
/* initialize your view controller here v and then push it */
SomeViewController *v = [[[SomeViewController alloc] init] autorelease];
[self.navigationController pushViewController:v animated:YES];
}
Dot confuse it with didDeselectRowAtIndextPath method - it happens as people do not pay much attention when selecting methods from intelisense.
Another place you can use this is inside viewDidAppear
- (void)viewDidAppear:(BOOL)animated
and insert the following
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
The cell stays selected after clicked and pushed to a different view controller, but deselects when it pops back to the original view controller, so it gives the user a visual cue for the last selected row.
quote SimonBS:
tried that and hoped it would work (to
get the animation) but it seems that
both viewDidAppear:(BOOL)animated and
viewWillAppear:(BOOL)animated aren't
called when in a subview.
the code by honcheng does work
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSIndexPath *indexPath = [self.tableViewOutlet indexPathForSelectedRow];
[self.tableViewOutlet deselectRowAtIndexPath:indexPath animated:YES];
}
you just need to use it on the TableView's superview. (For instance: if you have a xib file with a TableView subview inside the view you just need to go to the corresponding view controller code and override viewWillAppear, i just did it and it works! hello visual cue!)
My code looks like this:
NSIndexPath *ip = [NSIndexPath indexPathForRow:15 inSection:0];
[[self tableView] selectRowAtIndexPath:ip animated:YES scrollPosition:UITableViewScrollPositionMiddle];
// Pause needed here until animation finishes
[[self navigationController] pushViewController:secondView animated:YES];
Right now it animates the scroll/selection of the row and pushes the view controller at the same time. What I would like it to do is wait until it finishes the scroll/selection and then push the view controller. Is there any possible way of doing this? Thanks
The tableview should call scrollViewDidEndScrollingAnimation when the scrolling ends. Try putting the push in that method:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
if (weShouldPushSecondView)
{
weShouldPushSecondView = NO;
[[self navigationController] pushViewController:secondView animated:YES];
}
}
You might need to use a bool ivar that you set to YES right after the selectRowAtIndexPath because the scrollViewDidEndScrollingAnimation may be called at other times for other scrolls.
Is there a reason you don't push the view controller in your -tableView:didSelectRowAtIndexPath: delegate method? That method should be called once the animation is complete.
I am using iPhone SDK 3.1.3. I have a UITableViewController which gets data from another controller. The table view is added as a subview to the mainview but the frame is set so that it is not visible. The table view frame is updated and made to slide over the main view by tapping on a button.
The table view appears and I scroll to the last row. If I select the last row, I reload the table with more data. The table gets updated with more data. Everything works fine except the scroll position is always the top.
I need the scroll position to be the last row that I clicked on to load more data. I save the scroll position and call the following code after it loads more data. It executes without issues but the scroll position is always the top.
[theTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:savedScrollPosition inSection:0] atScrollPosition:savedScrollPosition animated:NO];
The above seems to have no effect. ViewWillAppear: ViewDidAppear: does not fire and I am told that if the view controller is instantiated in code, which is the case, these don't fire. Please help me figure out how and when to set the scroll position after the table is reloaded ([theTableView reloadData]) so that it is at the row that I clicked on.
Code to Reload table view & scroll
////performAction will notify the tableviewcontroller which will result in didPerformAction being called
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == lastRow)
{
savedScrollPosition = lastRow;
//perform the action
[controller performAction];
}
}
- (void) didPerformAction:(NSNotification *)obj
{
[theTableView reloadData];
[theTableView
scrollToRowAtIndexPath: [NSIndexPath indexPathForRow:savedScrollPosition inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:NO];
}
This seemed to do the trick.
[theTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:savedScrollPosition inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
CGPoint point = theTableView.contentOffset;
point .y -= theTableView.rowHeight;
theTableView.contentOffset = point;
It will look better and the scroll position will stay fixed if you can insert the rows instead of calling reloadData.
[theTableView beginUpdates];
[theTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
// make sure the dataSource will return new rows before calling endUpdates
[theTableView endUpdates];
Instead of using UITableView scrolling you can use UIScrollView scrolling:
savedOffset = [theTableView contentOffset];
Then restore:
[theTableView setContentOffset:savedOffset];
If that's the actual code and assuming theTableView is not nil there, you should be getting a warning saying "may not respond to..." because scrollToRowAtIndexPath is spelled wrong.
Secondly, the atScrollPosition parameter expects a UITableViewScrollPosition enum value indicating where on the screen you want the target row to be positioned.
Try this:
[theTableView scrollToRowAtIndexPath:
[NSIndexPath indexPathForRow:savedScrollPosition inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:NO];