I am trying desperately to make this IBAction just effectively press a cell at a selected row. I have managed to get it to select a row, but I can't work out how to effectively click on this cell! I am only making my first app but I have managed to figure most things out by myself, but just can't seem to find out how to do this, i'm hoping it is a simple solution (or there is a much better way to do it than I have).
Here is the code for my IBAction anyway:
- (IBAction)myButton:(id)sender {
// Specify which cell I wan't to select
NSIndexPath *myIP = [NSIndexPath indexPathForRow:0 inSection:0];
// Select it
[self.tableView selectRowAtIndexPath:myIP animated:NO scrollPosition:UITableViewScrollPositionTop];
// Click this cell??
}
Thanks in advance for any help
Just tell the delegate that you've selected it
[self tableView:self.tableView didSelectRowAtIndexPath:myIP];
Assuming that self is your VC that controls the table.
The below stackoverflow answer looks like exactly what you need...
Automatically cell selected UITableView
Not a clean way to achieve but as per my understanding, You can add custom UIButton (transparent) on each cell such a way it covers almost complete cell in cellForRowAtIndexPath:, disable row selection. On these button you can use addTarget:action:
If your view controller that has the UITableView in it, is not subclassing UITableViewController you need to create an IBOutlet of the UITableView call it myTableView or whatever you'd like, then in your IBAction you can reference it like this:
- (IBAction)myButton:(id)sender {
// Specify which cell I wan't to select
NSIndexPath *myIP = [NSIndexPath indexPathForRow:0 inSection:0];
// Select it
[self.myTableView selectRowAtIndexPath:myIP animated:NO scrollPosition:UITableViewScrollPositionTop];
// (Per Dmitry's answer)
[self.myTableView didSelectRowAtIndexPath:myIP];
}
Related
So it's easy to select a row that is currently in the UITableView. For example, to select the first row:
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionNone];
Say that I have an array that is the data source for the table and the array count is greater than the number of cells displayed in the tableview. How can I get the UITableView to scroll to an index from the array that is beyond what is currently being displayed in the tableview?
All I am trying to do is to replicate programmatically what a user would do with their index finger as they scroll down the table.
My specific table displays 9 rows. My array has 20+ items. As the UIViewController loads, it retrieves the row number that should be selected (from an integer stored in NSUserDefaults). But I find that it will only scroll to the correct array position if that integer value is between 0 and 8. If it is 9 or greater, nothing happens, and I can't figure out how to make it respond to this. I've looked at all the UITableViewDelegate methods and none seems to address this.
What I've been doing to scroll and select a specific row is this (example arbitrarily selecting row 11):
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:11 inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:11 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionTop];
Can anyone help me? I assume it isn't difficult, but I'm stuck.
Thanks!
Your cells that are off the screen ain't selecting because you are using reusable cells. The cells from the visible screen will be used later, it isn't that all 100 cells are cached and each cell is responsible for each row. What it means is that they could or couldn't have something in it already. For example, lets say you have cell for row 1. When it comes off the screen, in the next few cells it will be reused as cell 15 or something, and if it had selected properties, it will still have it. It is like a new job and you get a desk from the developer before you - you could have desk with his trash, but it could also be clean.
I wouldn't select them as you select them by method, but in if statement in your cellForRowAtIndexPath. Something along the lines (added comments):
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
// When using method with forIndexPath you don't have to check for nil because you will always get cell
MyTableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
MyObj *obj = [self.myArray objectAtIndex:indexPath.row];
cell.location.text = obj.location.location_description;
// other formatting, text display, image loading, etc.
if ([self.selectedObjects containsObject:obj]) {
// do some selecting stuff
} else {
// but don't forget to unselect because you can get already selected cell
}
return cell;
}
Edit: To select invisible cell, first scroll to it, then select:
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
Try using UITableViewScrollPositionBottom instead of UITableViewScrollPositionNone
That is use this code
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:10 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionBottom];
I figured this out. My code was running in viewDidLoad which is too early. I needed to move it to viewDidAppear. At least I know that I am not losing my mind.
I have a subclass of UITableViewController.
By default, it creates a UITableView when it is initialized. To that tableview I have set a header that I created in Interface Builder in the screen that is controlled by the controller. The header has two buttons:
one to enter editing mode for the tableview (called "Edit")
one to add a random item to the tableview (called "New").
I linked an IBOutlet property called headerView to the header from Interface Builder and I set it to be the header of the UITableView created at initialization in the viewDidLoad method.
The problem is that when I press the "New" button (which adds a new row with a new item to the tableview) the header of the tableview falls down to the bottom of the tableview.
Any idea why? How can I make it stick to the top?
This is the viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
[self.tableView setTableHeaderView:self.headerView];
}
This is the method that gets executed when the "New" button is pressed:
- (IBAction)addNewItem:(id)sender {
Item *newItem = [[ItemStore sharedStore] createItem];
NSInteger lastRow = [[[ItemStore sharedStore] allItems] indexOfObject:newItem];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
Thanks.
Possibly you've set up the layout for table header view in a wrong way. Was there any layout constraint on it?
By the way, this project on GitHub is a very simple example to demonstrate how simply it is to achieve what you want in the storyboard. It will produce the result like below:
Please use this project to compare with your current configuration.
I hope this helps in one way or another.
I am trying to programatically highlight a table view cell and trigger the selection logic by doing the following
NSIndexPath*indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
The row highlights only for a split second. I want it to stay highlighted until I select another row.
I tried adding these lines
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: indexPath];
cell.highlighted = YES;
but when I did this, the highlight remained even when I clicked on another row and did not go away until I clicked the first row again.
Any ideas?
Try calling selectRowAtIndexPath but not didSelectRowAtIndexPath. I believe the latter is called as a result of the former. If your delegate deSelects the last selected index path in didSelectRowAtIndexPath, then the double call would result in deselecting what you had just selected
seems like the issue was because I was calling the code from viewDidLoad, I moved it to viewDidAppear and now its fine
I am trying to implement a view similar to that of Apple's calendar application's setting the start time and end time view. I have the view looking great, but I am running into two problems. First, I want to have the first row selected automatically. I sort of have this working using:
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
[dateTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
However, an animation shows, visually selecting the rown when the view is loaded, I want it to already be selected when the view loads.
The second, and much more important, problem is that when I reload the data after the picker has updated I lose the selection, and my task simply doesn't work.
Now I know this is the default action of reloadData, I am looking for an alternative method to accomplish my goal, or perhaps how I can augment reloadData to not deselect the current selection.
My task is included below:
-(IBAction)dateChanged
{
NSIndexPath *index = self.dateTableView.indexPathForSelectedRow;
if(index == 0)
{
if (self.date2 == plusOne ) {
self.date = [datePicker date];
plusOne = [self.date dateByAddingTimeInterval:60*60];
self.date2 = plusOne;
}
else
{
self.date = [datePicker date];
}
}
else{
self.date2 = [datePicker date];
}
[dateTableView reloadData];
}
Note: plusOne is a variable that initially indicates an hour from the current time.
Thanks in advance!
For the first problem, set animated:NO on the method call. You are currently setting it to YES.
[dateTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];
For the second problem, it's not really clear what you are trying to select after reloading the data, but I see a problem with this line:
if(index == 0)
You are asking if the pointer to the object is 0. I think what you want is either to check that index == nil or that index.section == 0 && index.row == 0 or something like that.
Anyway, if you call reloadData on the UITableView, you're going to lose the selection. At that point, you need to select a new row. If there is an item in your data model that you want to select, you need to figure out where it is and select it based on where it will be in the table (You should know this because you are providing that information in the UITableViewDataSource delegate methods.). Alternatively, if you want to select the NSIndexPath you saved in the first line of dateChanged, just select it after reloading the data.
For the first problem, write your code in didSelectRowAtIndexPath: in a method. You can then call this method from didSelectRowAtIndexPath: You should pass indexPath as argument to your function like,
-(void)doActionsInDidSelectRow:(NSIndexPath*)indexPath{
// write code.
}
In viewDidLoad call this method as
-(void)viewDidLoad{
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
[dateTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
[self doActionsInDidSelectRow:indexPath];
}
For the second problem my suggestion is, each time when you selecting a cell store that cell's text in a NSString. When you reload data, inside cellForRowAtIndexPath: just compare cell's text with the string content you stored previously. If they equal just make selection using
[dateTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
method. Hope this will solve your issues.
I am using a splitviewcontroller. When I select something in the table the row is highlighted and it is shown in the detailed view. I have also provided an option to change the contents in the detailed view by scrolling.
When I start I want the the 5th row to be highlighted by itself, how can I do it?
Check out the following UITableView method:
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
I was using the above function from the start. But the app was crashing when I wrote this code into the viewDidLoad.
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:5 inSection:0];
[self.tableView scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
There is no data loaded into the UITableView instance. You can't select a row that doesn't exist. This was the reason it was crashing. And yes, this is the function that will help us do it.