Say, for example, I was wanting to edit the title for the highlighted state, is this possible?
I know it is possible with custom UIButtons, but is it possible to edit the properties of the UITableViewCellAccessoryDetailDisclosureButton?
If not, is it possible to create a custom button and still call a UITableView delegate method?
If so, how would one pass the indexPath from a custom button cell?
Cheers!
You can create a custom UIButton and assign it to the accessoryView property of your cell.
If you want to do sth. really custom for the highlighted state of cells you should consider subclassing UITableViewCell and override setSelected:animated:
give your custom button.tag=indexPath.row and access row no. from button tag
ex:-
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[deleteButton setFrame:CGRectMake(285, 5, 30, 30)];
deleteButton.contentMode = UIViewContentModeScaleAspectFill;
UIImage *newImage12 = [UIImage imageNamed:#"x.png"];
deleteButton.tag = indexPath.row;
[deleteButton setBackgroundImage:newImage12 forState:UIControlStateNormal];
[deleteButton setBackgroundImage:newImage12 forState:UIControlStateHighlighted];
[deleteButton addTarget:self action:#selector(deleteRemindersMethod:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:deleteButton];
-(void)deleteRemindersMethod:(UIButton *)sender
{
int rowNO=sender.tag;
}
To the best of my knowledge, you'll have to set your own button as the accessory view. There are several ways to get the indexPath and my preferred is to get the touch coordinates using locationInView: and then indexPathForRowAtPoint: to get the actual indexPath that you need:
CGPoint location = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
(code taken from here)
Related
I have a UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Where we configure the cell in each row
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
self.myButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.myButton.tag = 5;
self.myButton.frame = CGRectMake(190.0f, 5.0f, 70.0f, 25.0f);
self.myButton.layer.borderColor = [UIColor blackColor].CGColor;
self.myButton.layer.borderWidth = 0.5f;
self.myButton.backgroundColor = [UIColor grayColor];
[self.myButton setTitle:#"Set Active" forState:UIControlStateNormal];
[self.myButton addTarget:self action:#selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview: self.myButton];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
-(void) myButton:(id)sender{
[sender setBackgroundColor:[UIColor redColor]];
}
Assume, there 3 rows in the tableview section. I have the button in 3 rows.
At the first instance, the button in the first row should have red color and the other 2 rows should have gray color.
If I select the button in the 2nd row, then the button in the 2nd row should be red and the other 2 gray and so on. I haven't figured out a way to do it. Any suggestions?
I am able to change the color of the button I have selected from cell. But at the same instance, the previously selected button and all the other buttons(except the selected button) should be default color. At a time only one button will be highlighted, and that will always be the selected button at that instance.
I think the right way to do this - subclass UITableViewCell and declare own protocol that will inform delegate in which cell button was pressed, and in the delegate - loop through all cells and set default color for all and red color for selected.
I made demo project
Easy way is set different tag for each button. Like this:
button.tag = indexPath.row + c;
when 'c' is constant.
And in you method:
-(void) myButton:(id)sender{
for( int i=0; i<numberOfRowsInTable; ++i )
[(UIButton *)[self.view viewForTag:i+c] setBackgroundColor:[UIColor grayColor]];
[(UIButton *)sender setBackgroundColor:[UIColor redColor]];
}
But if you have 2 or more section in table this way may be not work
Take a look at this: How can I loop through UITableView's cells?
Loop through the cells and set the "inactive" buttons to gray.
Just try this code:
-(void) myButton:(id)sender{
NSLog(#"sender Tag=== %d",[sender tag]);
UIButton *btn=(UIButton *)sender;
[btn setBackgroundColor:[UIColor redColor ]];
}
I have one doubt that how to get other control's value when we select a row or tap on button while having custom tableViewCell.
Suppose I have a TableView Cell with a TextField, a Slider and button. Button has action using:
btn.tag = indexPath.row;
[btn addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
Now I can get button on its action method. I need to get textField's value and slider's value on button tap.
The one option is I create a array and store values for these two control in that array and manage this. But I don't think this is correct way to manage it.
Please navigate me to the currect way to get value of UITableViewCell's subview's value.
Thanks
While creating your textfield and slider, give them a constant tag and then add to cell's contentView
textfield.tag= TEXTFIELDTAG; //TEXTFIELDTAG = 100 or any other constant
[cell.contentView addSubview:textfield];
and then in your buttonTapped: method
-(void)buttonTapped:(id)sender
{
int row = ((UIButton*)sender).tag;
NSIndexPath* indexpath = [NSIndexPath indexPathForRow:row inSection:0]; // in case this row in in your first section
UITableViewCell* cell = [table cellForRowAtIndexPath:indexPath];
UITextField* textfield = [cell.contentView viewWithTag:TEXTFIELDTAG];
}
Whenever you create subviews (button , text field etc. ) for your UITableViewCell don't forget to tagged them.
myTextField.tag = 0;
myTextLabel.tag = 1;
[cell addSubview:myTextField];
[cell addSubview:myTextLabel];
Once you tagged, you could access them using below method.
- (UIView *)viewWithTag:(NSInteger)tag
When you select,you could get the subviews of your UITableViewCell's by using ViewWithTag function of UIView.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableview cellForRowAtIndexPath:indexPath];
UITextField* myTextField = [cell viewWithTag:0];
UILabel* myTextLabel = [cell viewWithTag:1];
}
I have subclassed a UITableViewCell. What I want to have is when I click on the cell, I added a UIView to the bottom of the cell and adjust the height of the cell accordingly. Here's my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell* cell = (MyCell *) [self.table cellForRowAtIndexPath:indexPath];
UIView * options = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height - 27, cell.frame.size.width, 27)];
UIButton* button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[options addSubview:button1];
UIButton* button2 = [UIButton buttonWithType:UIButtonTypeCustom];
[options addSubview:button2];
UIButton* button3 = [UIButton buttonWithType:UIButtonTypeCustom];
[options addSubview:button3];
//did some layout calculation here to position the button
[cell addSubview:options];
}
Here's a video that illustrates the issue
Also I've tried to change the accessoryView of my cell from my custom UIButton to the regular UITableViewCellAccessoryDisclosure but it didn't work
MyCell * cell = (MyCell *)[self.table cellForRowAtIndexPath:temp];
[cell.accessoryView removeFromSuperview];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
If you're curious what I am trying to do, I am trying to create a tweetbot uitableviewcell, where you press the cell/row and it presents you with other options (retweets, etc) and also it was shown animated.
I don't know if I correctly understand what you are trying to do. But if you do want to animate the change of the UITableViewCell's height try to adjust it within - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath and call
[tableView beginUpdates];
[tableView endUpdates];
Put controls into another cell and use
insertRowsAtIndexPaths:withRowAnimation:
to show it and
deleteRowsAtIndexPaths:withRowAnimation:
to hide it.
Inside my cellForRowAtIndexPath method, I would like to dynamically create some buttons and place them next to each other in the cells. The problem I'm running into is that the sizeToFit method always puts the x coordinate at the 0 position. Is there a way to offset the position to put it next to the previous button?
Instead of this: . I get this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
if ([indexPath section] == 0) {
UIButton *buttonClean = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[buttonClean addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[buttonClean setTitle:#"Clean Cup" forState:UIControlStateNormal];
[buttonClean sizeToFit];
[cell addSubview:buttonClean];
UIButton *buttonAroma = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[buttonAroma addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[buttonAroma setTitle:#"Aroma" forState:UIControlStateNormal];
[buttonAroma sizeToFit];
[cell addSubview:buttonAroma];
You should position UIViews by setting their frame property.
This is an option:
[buttonAroma setFrame:CGRectMake(buttonClean.frame.size.width,0,buttonAroma.frame.size.width,buttonAroma.frame.size.height)];
you should also add your views to the cell's contentView, instead of adding them to the cell directly:
[cell.contentView addSubview:buttonAroma];
See UIView's frame property here:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instp/UIView/frame
See UITableViewCell's contentView property here:
http://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/contentView
.. where it says:
If you want to customize cells by
simply adding additional views, you
should add them to the content view so
they will be positioned appropriately
as the cell transitions into and out
of editing mode.
It's not the sizeToFit method that's putting them at y=0, it's the fact that you never set any other position. You can move each button by assigning its center or frame properties; for the latter, you would of course want to read out the property, modify just the origin of the CGRect, and set it back to the property so as to not mess up the sizing.
I'm trying to create a button in each tableviewcell and upon selected, the "Checked.png" should appear on the button.The default is "uncheck.png". However, the problem is the image always remain in "uncheck.png" regardless of the button being selected. It's driving me mad. Please help me on this. Would greatly appreciate if someone could provide some code snippets.Thank You
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:NULL];
cell = nibLoadedCell;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(270.0, 10.0, 60.0, 60.0)];
[button setImage:[UIImage imageNamed:#"Uncheck.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"Checked.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(Selected:) forControlEvents:UIControlEventTouchUpInside];
button.tag = indexPath.row;
[cell.contentView addSubview:button];
}
Look at the TouchCells example in XCode. Go to Help -> Developer Documenation and search TouchCells. Have a look at that sample project in XCode
As per documentation
For many controls, UIControlStateSelected state has no effect on behavior or appearance.
I think the same for UIButton also.
What I would suggest is you can set the button setImage property again to Checked.png in the didSelectRowAtIndexPath delegate of tableview.You should also set a unique tag for each button for identifying the button which you have to set the Checked.png Image.