I have a custom tableViewCell which has 3 actions associated with it.
Where do I handle these actions and handle the row on which they are taking place?
For example, if button2 is pressed on table row 3, how is this handled?
Thanks
What I would do is a conditional for where you want to place your buttons and then add the targets and selectors to those buttons.
For example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//Do your conditionals like this
if(indexPath.row == 2){
[cell.yourButton addTarget:self action:#selector(yourMethod:)
forControlEvents:UIControlEventTouchUpInside];
}
//another row another method
else if(indexPath.row == 4){
[cell.yourOtherButton addTarget:self action:#selector(yourOtherMethod:)
forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
Related
Hi I have a table view with static cells. I want to hide specific ones with a button. I must hide them according to the current time of the iphone so i created UITableViewCell outlets for each of them. How can i hide a cell when the button is clicked ? Thanks in advance.
I get what you want to do. if you want to hide action, you need to control your static tableView.
Don forget to reload tableview in your action.
[self.tableView reloadData];
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
cell.hidden=YES;
return 0;
}else{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
cell.hidden=NO;
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
return cell;
}
i want to add 2 or more diffrent Custom cells in one Tableview, by using storyboard.
i know how to add diffrent cells without storyboard. I always do this by this way:
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//pictureCell = [[DetailPictureCell alloc]init];//(DetailPictureCell *)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
pictureCell.header = true;
[pictureCell setHeader];
if (cell == nil) {
if ([indexPath row] == 0) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"HeaderAngebotViewCell" owner:self options:nil];
NSLog(#"New Header Cell");
}
if([indexPath row] ==1){
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"productCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
And now my question: How i can do this with storyboard?
To add one custom cell is possible. But i can not add two diffrent cell. Can you help me please?
In the attributes inspector for the table view, select "Dynamic Prototypes" and below that select the number of prototype cells. Give each cell a different identifier and when dequeuing cells in cellForRowAtIndexPath, use the appropriate identifier based on indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier;
if (indexPath.row == 0) {
identifier = #"OneCellId";
} else if (indexPath.row == 1) {
identifier = #"OtherCellId";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//configure cell...
}
I'd like to do following: After clicking a row in a tableview, I want to set value of some variable and in the same time change the cell accessory type to checkmark. Here is my implementation file:
- (void)viewDidLoad
{
[super viewDidLoad];
tabledata = [[NSArray alloc] initWithObjects:#"row1", #"row2", #"row3", nil];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tabledata count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Row"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Row"];
}
cell.textLabel.text = [tabledata objectAtIndex:indexPath.row];
return cell;
}
#pragma mark TableVoew Delegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//if row1 is selected change 'value' to 1 and change cell accessory to checkmark (other cells accessory to none)
//if row2 is selected change 'value' to 2 and change cell accessory to checkmark (other cells accessory to none)
//if row3 is selected change 'value' to 2 and change cell accessory to checkmark (other cells accessory to none)
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.value = indexPath.row;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:nowIndex];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
EDIT
Set only the accessory for selected row in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell.accessoryType = UITableViewAccessoryNone;
if (indexPath.row == self.value) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
See this to remove checkmarks from currently visible cells in tableview.
EDIT 2
To unselect the previous row, do this in didSelectRowAtIndexPath
NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:index inSection:1];
NSLog(#"Oldindexpath is: %#", oldIndexPath);
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
if (newCell.accessoryType == UITableViewCellAccessoryNone) {
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:oldIndexPath];
if (oldCell != newCell){
if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
}
This solved my problem with removing old checkmarks:
for (UITableViewCell *cell in [tableView visibleCells]) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
and problem with setting value of current row was solved in previous answer.
I have a tableview with two actions in it, for the first on i use the delegate didSelectRowAtIndexPath, for the second one i would like to use an action on a button on my cell to do something else. My problem is that i don't succeed to get the indexpath ? What is the best practice to do that.
If you have added the button to the cell as,
[cell.contentView addSubview:button];
then, you can get the index path as,
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Go ahead
}
I'm using this solution -- getting index path of cell using points
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
Its work perfectly
here is the full code for a custom button:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCellFilter *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {cell = [[CustomCellFilter alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}
//configure your cell here
cell.titleLabel.text = #"some title";
//add button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
resetButton.frame = CGRectMake(40, 10, 18, 18);
[resetButton addTarget:self action:#selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[resetButton setImage:[UIImage imageNamed:#"someimage.png"] forState:UIControlStateNormal];
[cell.contentView addSubview:myButton];
//afterwards return the cell
return cell;
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [filterTable indexPathForCell:cell];
NSLog(#"%#", indexPath);
//use indexPath here...
}
In case you are using a collection view, you can use Yogesh method, but change indexPathForRowAtPoint for indexPathForItemAtPoint like this:
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
In case that your button is moved or Apple changes the view hierarchy for accessory views, this method goes up the chain to look for a UITableViewCell:
- (void)tapAccessoryButton:(UIButton *)sender {
UIView *parentView = sender.superview;
// the loop should take care of any changes in the view heirarchy, whether from
// changes we make or apple makes.
while (![parentView.class isSubclassOfClass:UITableViewCell.class])
parentView = parentView.superview;
if ([parentView.class isSubclassOfClass:UITableViewCell.class]) {
UITableViewCell *cell = (UITableViewCell *) parentView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}
}
I have an app where I load a UIViewController with an UITableView. In the UITableViewCells I have a UITextField. Which I have added in the cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
if ([indexPath section] == 0) {
// Setting the cell textLabel.
[[cell textLabel] setText:[Customize objectAtIndex:indexPath.row]];
if ([indexPath row] == 0) { // Text
// Adding and customizing UITextField.
TextFieldText = [[UITextField alloc] initWithFrame:CGRectMake(160, 10, 140, 30)];
TextFieldText.placeholder = #"Random";
TextFieldText.autocorrectionType = UITextAutocorrectionTypeNo;
TextFieldText.autocapitalizationType = UITextAutocapitalizationTypeNone;
TextFieldText.returnKeyType = UIReturnKeyDone;
[cell addSubview:TextFieldText];
and so on.
The problem is that when you type in it, it is a little slow. When a letter/symbol is typed it appears in the UITextField and for a very short second the marker is still on the left side of the letter/symbol and slide across the letter/symbol. The keyboard also appears kind of slow.
Any thoughts?
Thanks in advance :)