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];
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've 3 tableviews in my view and I want to enable scroll to top feature for all tables at the same time, i.e., if the user taps on status bar all the three tables should be scrolled to top position.
I've tried using scrollsToTop property of all my tableViews and also various combinations of YES/No for this property. for example
table1.scrollsToTop = YES;
table2.scrollsToTop = NO;
table3.scrollsToTop = NO;
but not able to achieve this. Do we have any way out to get the event of tap on status bar so that I may try to set the content offset of all the tables to top position or any other work around.
Any help would be appreciated.
Solved this problem by overriding scrollViewShouldScrollToTop method like below, -
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
[table1 scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[table2 scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[table3 scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
return NO;
}
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.
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];
I have UITableView that has custom cells representing a player. When I add a new player a new data item is added and [UITableView reloadData] is called. Part of the cell is a UITextView that contains the player name. How do I bring up the keyboard for it?
I could use becomeFirstResponder if I had access to the UITextView in the cell but it hasn't actually been created yet. Since reloadData doesn't actually perform the creation of the new cell yet.
Someone else must have solved this before. Any tips on how to make this work would be greatly appreciated.
My code snippet:
-(IBAction)addPlayerPressed:(id)sender {
Player *newPlayer = [Player alloc];
[players addObject:newPlayer];
[table reloadData];
// Scroll to bottom showing the new player location
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([players count] - 1) inSection:0];
[table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// cell is always nil :(
PlayerTableCell *cell = (PlayerTableCell *)[table cellForRowAtIndexPath:scrollIndexPath]
[cell.nameField setfirstResponder];
}
Couple of things:
You're probably better off using UITextField instead of UITextView. UITextField is ideal for single-line entries like what you're describing here.
As for your solution, here's what I'd recommend. (Also took the liberty of cleaning up your memory management)
Add a BOOL property to your Player class called, say, 'needsKeyboardDisplay', then set it to yes after you create a new instance.
-(IBAction)addPlayerPressed:(id)sender {
Player *newPlayer = [[Player alloc] init];
newPlayer.needsKeyboardDisplay = YES;
[players addObject:newPlayer];
[newPlayer release];
[table reloadData];
// Scroll to bottom showing the new player location
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([players count] - 1) inSection:0];
[table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
Then, in cellForRowAtIndexPath, insert this after you've otherwise set up your cell:
Player *playerForCell = [players objectAtIndex:indexPath.row];
if (playerForCell.needsKeyboardDisplay)
{
[nameField becomeFirstResponder];
playerForCell.needsKeyboardDisplay = NO;
}
All that said, from a user experience perspective, the (somewhat) standard iPhone experience for editing details in a long list of items like this is to do it in another view. It's up to you, of course.
Can u make the textfields delegate the UITableviewController instead Of the table cell?
In your PlayerTableCell class, you could put some code in the -initWithStyle:reuseIdentifier: method that checks to see if it should become first responder and, if so, does. You probably have a PlayerController class or something similar; you might make a delegate method for the custom table view cell or something similar.