I need to get the the currently selected UITableViewCell as its tapped. So upon my finger touching the screen/cell I want to run a method from which I can say something as simple as:
selectedCell = cell;
cell being the one I just tapped and selectedCell being a copy I store.
I am using a custom subclassed UITableViewCell which is why I think I'm having trouble.
Just implement setHighlighted:animated: method on your own custom tableview cell like this.
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
NSLog (#"setHighlighted:%# animated:%#", (highlighted?#"YES":#"NO"), (animated?#"YES":#"NO"));
}
TouchDown
- setSelected:animated: is called on the cell itself on touch down here, you can inform a cells delegate
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[self.delegate willSelectCell:self];
}
declare custom cells delegate as property of the cell
#property id<MyCellDelegate> delegate;
TouchUP
save the cell in the delegate
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
_selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
}
just pay attention to the fact that Cell Views can be reused
Related
When we select UITableViewCell than - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath called.
But which method will be called if we hold the UITebleViewCell. Guys my problem is that I have created a tableview which contain large cell and in that cell I am setting various view an view's background color.
When I select the cell, the background color of my cell will be gone. I have solved this problem by setting view background color again in didSelectRowAtIndexPath method like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
UIView *vLineview=[selectedCell viewWithTag:1];
vLineview.backgroundColor = [UIColor colorWithRed:(89/255.0) green:(89/255.0) blue:(89/255.0) alpha:1];
}
This done the trick and my view background color will displayed but when I hold the UITableViewCell than it will gone again.
How can I solve this? Do I have to and gesture recognizer to detect long touch and implement my view background method in it? Or there is any other method available for that.
Try with set cell selection style none like this in cellForRowAtIndexPath
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
You can subclass UITableViewCell and override this method:
- (void) setSelected: (BOOL) selected
animated: (BOOL) animated
{
[super setSelected: selected
animated: animated];
// Configure the view for the selected state
}
Is this an issue with the UITableViewCell remaining selected after you tap on the row?
If row selection is not required, make sure you call deselectRowAtIndexPath:animated at the end of your tableView:didSelectRowAtIndexPath method.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Pleasese see method named -(void)beginUpdates
Call this method if you want subsequent insertions, deletion, and selection operations (for example, cellForRowAtIndexPath: and indexPathsForVisibleRows) to be animated simultaneously.
for more detail visit apple documentation in below link
UITableView Class Refrence
Also try [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
I am using custom UITableViewCell with a nib file with name "MyCellNib",for example.
I my tableviewcontroller i register in viewDidLoad this nib like this:
[_table registerNib:[UINib nibWithNibName:#"MyCellNib" bundle:nil]
forCellReuseIdentifier:#"cell"];
in my cellForRowAtIndexPath: it looks like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
cell = [_table dequeueReusableCellWithIdentifier:#"cell"];
cell.clipsToBounds = NO;
return cell;
}
As u see i dont use standart pattern like if(cell == nil) etc.(as we do it in iOS4) - regiserNib method can do it for us.
So, the problem: I need to write some code in the cell subclass.
in my custom uitableviewcell subclass the method
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
is not called (i used it before to customizw the cell), but i need it to add some stuff on contentView programmaticaly..
Is there any way to customize my custom cell when it is created?
Figured it out.
All this pre-stuff can be performed in -(void)awakeFromNib method
I can not set the custom cells accessory view while the page loads for the first time, any ideas?
In DetailView customcell's class I have this:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if(self.selected)
self.accessoryType=UITableViewCellAccessoryCheckmark;
else
self.accessoryType=UITableViewCellAccessoryNone;
}
And In tableview controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewCell *cell = [DetailViewCell cellForTableView:tableView];
if(somelogichere){
[cell setSelected:YES];
}
return cell;
}
I debug and hit that line so logic is true, but in debug I also see that after it sets the accesory then again it calls twice the selected method, which overrrides the accessory to none in the else inthe second call. setSelected causes the selected method to be called twice and overrides the setting on the second call cause somehow on second call self.selected returns false;
UPDATE: I solved the problem by creating a boolean cellSelected property in the custom cell class and changing and checking its status rather than setting and changing the selected property of the cell, this is also better cause I can support multi selection tableview's better in future.
Does it work the second time after the view has loaded?
It most probably has something to do with following line:
if(somelogichere){
[cell setSelected:YES];
}
What is somelogichere ?
Depending on somelogichere your selected property might not be true the first time you run your code:
if(self.selected)
self.accessoryType=UITableViewCellAccessoryCheckmark;
else
self.accessoryType=UITableViewCellAccessoryNone;
Make sure you set your cell's selected property in the beginning. Or change the code inside your setSelected.
HTH
You try this code its help u
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
UIImage *selectionBackground = [UIImage imageNamed:#"list_BG.jpg"];
UIImageView *iview=[[UIImageView alloc] initWithImage:selectionBackground];
self.selectedBackgroundView=iview;
}
OR
In cellForRowAtIndexPath method of tableView:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
The cell in this iPhone TableView definitely has a Detail-Disclosure-Button.
When I tap it... shouldn't this code give me access to the button?
Instead detailButton is always just null.
- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *aCell = [tableView cellForRowAtIndexPath:indexPath];
UIButton *detailButton = (UIButton *)[aCell accessoryView];
}
are you over-riding the cell accessory button in 'cellForRowAtIndexPath' by any chance?
accessoryView is provided for your own customization, to override accessoryType. The table view cell will internally handle whatever you assign to accessoryType without affecting accessoryView.
I created a tableViewCell the include an image, two text labels and a uibutton.
The button is allocated to an action method (e.g. viewButtonPused:sender).
I'm used to handle row selection with tableView:didSelectRowAtIndexPath: so I could tell which row was selected. But with the uibutton and its action method .... How can I tell?
Thanks in advance.
If the button's target is the UIViewController/UITableViewController or any other object that maintains a reference to the UITableView instance, this will do nicely:
- (void)viewButtonPushed:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = button.superview; // adjust according to your UITableViewCell-subclass' view hierarchy
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// use your NSIndexPath here
}
Using this approach will let you avoid extra instance variables and will work fine in case you have multiple sections. You need to have a way to access the UITableView instance though.
Edit: as someone pointed out in the comments below, this approach broke in iOS 7. If you're still interested in using this approach over tags, be sure to find the UITableViewCell instance correctly, i.e. by looping through the superviews until you find one.
Define a delegate on the class associated with the Cell's prototype.
// MyCell.h
#protocol MyCellDelegate
- (void)buttonTappedOnCell:(MyCell *)cell;
#end
#interface MyCell : UITableViewCell
#property (nonatomic, weak) id <MyCellDelegate> delegate;
#end
// MyCell.m
#implementation MyCell
- (void)buttonTapped:(id)sender {
[self.delegate buttonTappedOnCell:self];
}
}
#end
Now go to the class you want to make the Cell's delegate. This is probably going to be a UITableView subclass. In the cellForRowAtIndexPath method make sure you assign the delegate of the Cell to self. Then implement the method specified in the protocol.
- (void)buttonTappedOnCell:(MyCell *)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
int row = indexPath.row;
}
Or if you would prefer a blocks based approach:
// MyCell.h
typdef void(^CellButtonTappedBlock)(MyCell *cell);
#interface MyCell : UITableViewCell
#property (nonatomic, copy) CellButtonTappedBlock buttonTappedBlock;
#end
Then in your tableView's dataSource:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = ....
__weak typeof(self) weakSelf = self;
[cell setButtonTappedBlock:^(MyCell *cell) {
NSIndexPath *indexPath = [weakSelf.tableView indexPathForCell:cell];
// Do stuff with the indexPath
}];
}
I know this is an old thread but I find this method best as it is free from superView calls (and thus when Apple change the view hierarchy with new os versions it is left unaffected) and doesn't require subclassing or use of cumbersome tags that can get messed up when the cell is reused.
- (void)buttonPressed:(UIButton *)sender {
CGPoint location = [sender convertPoint:sender.center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
NSLog(#"%#", indexPath);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.customCellButton addTarget:self action:#selector(customCellButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell.customCellButton setTag:indexPath.row];
}
- (void)customCellButtonTapped:(id)sender {
UIButton *button = (UIButton *)sender;
NSLog(#"indexPath.row: %d", button.tag);
}
If you have directly added elements on the cell itself (which you shouldnt) -
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview] ];
If you have added elements on the contentView of the cell (which is the proposed way)
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview] ];
define one class variable int SelectedRow; inside didSelectRowAtIndexPath assign value to it like
SelectedRow = indexPath.row;
use this SelectedRow variable in side your action method viewButtonPused:sender
Instead of adding the button as a subview of the cell set it to be cell.accessoryView.
Then use tableView:accessoryButtonTappedForRowWithIndexPath: to do your stuff that should be done when a user taps this button.
Another way that I use now is to subclass UIButton and add a property of type NSIndexPath.
On cellForRowAtIndexPath I assign the value of indexPath and its available at the action method.