The code below seems to have no effect. I want it to be highlighed in the same way it highlights when you tap on a row
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
[cell.textLabel setHighlighted:YES];
return cell;
}
This line will handle repainting the cell, label and accessory for you:
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
As others have noted, you can programmatically select a cell using this method:
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
However, you should be careful not to call this method too soon.
The first time that the view controller containing said tableView is initialized, the earliest that you should call this method is within viewDidAppear:.
So, you should do something like this:
- (void)viewDidAppear:(BOOL)animated
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; // set to whatever you want to be selected first
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
If you try putting this call into viewDidLoad, viewWillAppear:, or any other early view lifecycle calls, it will likely not work or have odd results (such as scrolling to the correct position but not selecting the cell).
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection: 0];
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
usually works
If you are using interface builder to build your interface, one thing to check is that you specified the view of the table view controller. If you don't actually specify the view, this selection message may go nowhere.
(you specify the view by selecting the table view controller in the interface builder inspector window and dragging the outlet for "view" to the table view you want to do the selection in).
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// do something here
}
Try this :)
You can useĀ
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
[cell.textLabel setHighlighted:YES];
return cell;
}
You have two choices. Either use the selection of the table view:
[tableView selectRowAtIndexPath: indexPath animated: YES scrollPosition: UITableViewScrollPositionNone];
Or change the background color of the table cell in the table view delegate:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = ...
}
Related
I want to be able to select multiple rows like the default mail app shown below:
I have a button called edit that calls
[self.myTableView setEditing:YES animated:YES]
The edit button successfully shows the circles on the left of the cells like the mail app as shown above. However, when I actually select one of the rows, nothing happens. The red checkmark does not appear in the circle as I would expect. Why isn't the red checkmark appearing?
#pragma mark - UITableViewDataSource Methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"];
}
cell.textLabel.text = #"hey";
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
#pragma mark - UITableViewDelegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return 3;
}
#pragma mark - Private Methods
- (IBAction)editButtonTapped:(id)sender {
if (self.myTableView.editing) {
[self.myTableView setEditing:NO animated:YES];
}
else {
[self.myTableView setEditing:YES animated:YES];
}
}
You have to explicitly set selection to be enabled during editing mode:
[self.tableView setAllowsSelectionDuringEditing:YES];
Or
[self.tableView setAllowsMultipleSelectionDuringEditing:YES];
According to the docs: these properties are set to NO by default.
If the value of this property is YES , users can select rows during
editing. The default value is NO. If you want to restrict selection of
cells regardless of mode, use allowsSelection.
Additionally, the following snippet of code may be causing problems with your selection because it immediately deselects the row as soon as it's been selected.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I am making a custom UITableView menu selector component. Every time I selected a specific row, I save this row's indexpath, so the next time when a user to select another row, people can know his previous selected row. So I added this into cellForRowAtIndexpath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell.textLabel.text = self.left[indexPath.row][#"name"];
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.highlightedTextColor = [UIColor grayColor];
return cell;
}
and when the user select another row, save this row to :[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow], so next time he can see his previous selected row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:indexPath.row] forKey:kPreviousSelectedRow];
}
The crash log: index is [[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] and count is numberOfRows. As you can see, it shouldn't out of bounds. I don't know where the [0...6] come from.
2013-08-23 21:01:26.107 [17605:c07] index:10, count:14
2013-08-23 21:01:26.173[17605:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 7 beyond bounds [0 .. 6]'
EDITED:And If I scroll the tableview slow, it won't crash, if I scroll it fast, it crashes. what?
You get a crash because at this exact time you have no cell with specified index because you're just preparing it inside your - (UITableViewCell*)tableView:cellForRowAtIndexPath:
To get behaviour you're expecting move selectRowAtIndexPath: out of - (UITableViewCell*)tableView:cellForRowAtIndexPath: and place it inside another method where you're updating your UITableView: -(void)viewDidLoad or where you call -(void)reloadTable for example
Your app is crashing because it is trying to select a row that it may not be currently visible. You are trying to select a row in your data source method "cellForRowAtIndexPath" when the data may not be completely available yet. That is why you get the out of bounds error.
For your specific example, you could try to select the previously selected row inside your "didSelectRowAtIndexPath" before you update the value, it will not crash here since your data has been already displayed.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:indexPath.row] forKey:kPreviousSelectedRow];
}
SVGreg was right. You should work with cell inside another method. But viewDidLoad not best option. You may try this useful method of delegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
Shouldn't be inside cellForRowAtIndexpath.
Get your indexPath from didSelectRowAtIndexPath which is triggered every time the user selects a cell.
If you want to trigger another method when the user deselects a cell or selecting another cell use
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
You could make a array with the capacity equal to your number of rows. Probally populate it with NO BOOL values (actually [NSnumber numberWithBool:] since they need to be objects).
Then in
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
change the value of the object at position indexPath.row,
And in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
check if the BOOL value from your array is set on YES then select the cell. (cell.selected = YES)
You could go the extra mile and make a custom cell with a custom selection style or something and make a method on the cell that will apply your selected design and call that method in cellForRowAtIndexPath.
Oh, I just replace selectRowAtindex to layoutsubview, and it won't crash, now. thanks SVGreg's hint.
I have created a custom cell that places a UITextField in each row of a UITableView. What I would like to do is enable the UITextField for a particular row (i.e. activate the cursor in that textfield), when the user presses on anywhere inside the cell.
I have the following method where I try to do this:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_cell.textField setUserInteractionEnabled:TRUE];
}
However, this is not working. Can anyone see what I'm doing wrong?
You're on the right track placing this inside didSelectRowAtIndexPath:. However, setting user interaction enabled on the textfield just means that the user would be allowed to interact with the object if they tried. You're looking for becomeFirstResponder.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
Try this code:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_cell.textField becomeFirstResponder];
}
What is this _cell iVar? Are you setting it somewhere?
I think what you are trying to accomplish is this:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
Notice that in this way you are getting the cell for the tapped indexPath.
And also, just for information, it's a pattern in objective-C to use booleans as YES or NO, instead of true or false.
What I was trying - I have a UITableView. On selecting any particular row it should show a selectionColor(Blue etc) and then it should disappear. Any property/code to do this? I am actually applying in in MyCalender view.
You can use [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
in your - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
method.
You should refer the delegates and datasource in tableview for this
The datasource sets the inputs to table
The delegate gives you callbacks of actions on the tableview .
So write the delegate methods ,include it in classdef UITableViewDelegate,connect it in xib
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This delegate method is invoked if you click on a particular row.The particular row is the row at the "indexpath"
finally include this line which deselect the code
[tableView deselectRowAtIndexPath:indexPath animated:YES];
add this to your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
`
UIView *violetColor = [[[UIView alloc] init] autorelease];
//violetColor.backgroundColor = [UIColor colorWithRed:0.824 green:0.749 blue:0.553 alpha:0.70];
violetColor.backgroundColor = [UIColor colorWithRed:0.724 green:0.749 blue:0.953 alpha:0.70];
cell.selectedBackgroundView = violetColor;
`
and then add this to your didselect `
if (indexPath != nil) {
[mTableView deselectRowAtIndexPath:indexPath animated:YES];
}
`.i hope this will do the trick.
In delegate method didSelectRowAtndexPath use this code
[tableView deselectRowAtIndexPath:indexPath animated:YES];
If you are using UITableView and want to remove selection of the UITableViewCell. Then you have to use the below code to deselect tableview cell.
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
In my tableview I have number of rows that have disclosure detail button accessory type, and when pressing the row or the accessory, a new view is pushed to a navigation controller. I call the deselectRowAtIndexPath at the end of the didSelectRowAtIndexPath function.
If I press the accessory button, I go to a new view, but it remains highlighted when I come back to this view (pop). The row is deselected as expected but not this. Any thoughts on how to 'unhighlight' it?
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
...
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
[self tableView:tableView didSelectRowAtIndexPath:indexPath];
}
For those who are still bothered by this and want a solution that appears to work right now, try this:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
You must reload the data FIRST and THEN select the row so that the highlight appears beneath your action sheet options.
Simply remove from your
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
method the statement
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
Since your table already allows selection, and you are correctly deselecting it in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
you are done, because the row will be highlighted when selected pressing the disclosure button, and deselected when tableView:didSelectRowAtIndexPath: is executed.