Currently I'm trying to customize delte button in UITableViewCell.
Now I've got something like that:
Now, all what I need is to change the color of this button, I don't want to change the behavior, or to make it absolutelly custom. I'm sure that it is possible, without creating your own controls for deleting rows in UITableView.
This my code:
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
deleteButtonView.backgroundColor = [UIColor greenColor];
}
}
}
How could I do this?
Thanks in advance!
UITableViewCellDeleteConfirmationControl is not a public class and you cannot easily change its appearance.
In order to do so I believe you'd have to iterate through the subviews of the cell and change its properties:
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl") {
// Set the background using an image.
}
}
Of course, you should be wary of doing this sort of thing since its rather fragile. I'd suggest rolling your own instead.
I'd suggest submitting a bug report to Apple to request the ability to edit this more easily.
In the UITableViewCell subclass:
- (UIView*)recursivelyFindConfirmationButtonInView:(UIView*)view
{
for(UIView *subview in view.subviews) {
if([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationButton"]) return subview;
UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
if(recursiveResult) return recursiveResult;
}
return nil;
}
-(void)overrideConfirmationButtonColor
{
dispatch_async(dispatch_get_main_queue(), ^{
UIView *confirmationButton = [self recursivelyFindConfirmationButtonInView:self];
if(confirmationButton) confirmationButton.backgroundColor = [UIColor orangeColor];
});
}
Then in the UITableViewDelegate:
-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
<#Your cell class#> *cell = (<#Your cell class#>*)[self.tableView cellForRowAtIndexPath:indexPath];
[cell overrideConfirmationButtonColor];
}
This works in iOS 7.1.2
Here's how to:
activate the delete button on swipe
// make sure you have the following methods in the uitableviewcontroller
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"You hit the delete button.");
}
set custom text label instead of delete.
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"Your Label";
}
set custom color for button part 1 - warning, this technically involves poking at the private apple API. However, you are not prevented from modifying a subview using a public method search that is part of UIKIT.
Create a uitableviewcell class (see also https://stackoverflow.com/a/22350817/1758337 )
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews) {
//iterate through subviews until you find the right one...
for(UIView *subview2 in subview.subviews){
if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
//your color
((UIView*)[subview2.subviews firstObject]).backgroundColor=[UIColor blueColor];
}
}
}
}
Another note: there's no guarantee this approach will work in future updates. Also beware that mentioning or using the private UITableViewCellDeleteConfirmationView class may lead to AppStore rejection.
set custom color for button part 2
back in your uitableviewcontroller
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
[YourTableView reloadData];
}
(The alternate color won't be called until the next time layoutSubviews is called on the tablecell, so we ensure this happens by reloading everything.)
silyevsk's example is excellent... but, six months later, iOS 8 has come along, and it doesn't quite work properly anymore.
Now, you need to look for a subview called "_UITableViewCellActionButton" and set the background color of that.
Below is a modified version of silyevsk's code which I've used in my app.
On some of my UITableView cells, I didn't want the user to be able to swipe-to-delete, but I did want something (a padlock icon) to appear when they swiped.
To do this, I added a bReadOnly variable to my UITableViewCell class
@interface NoteTableViewCell : UITableViewCell
. . .
@property (nonatomic) bool bReadOnly;
-(void)overrideConfirmationButtonColor;
@end
and I added silyevsk's code to my .m file:
- (UIView*)recursivelyFindConfirmationButtonInView:(UIView*)view
{
for(UIView *subview in view.subviews) {
if([NSStringFromClass([subview class]) rangeOfString:@"UITableViewCellActionButton"].location != NSNotFound)
return subview;
UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
if(recursiveResult)
return recursiveResult;
}
return nil;
}
-(void)overrideConfirmationButtonColor
{
if (!bReadOnly)
return;
dispatch_async(dispatch_get_main_queue(), ^{
UIView *confirmationButton = [self recursivelyFindConfirmationButtonInView:self];
if(confirmationButton)
{
confirmationButton.backgroundColor = [UIColor lightGrayColor];
UIImageView* imgPadLock = [[UIImageView alloc] initWithFrame:confirmationButton.frame];
imgPadLock.image = [UIImage imageNamed:@"icnPadlockBlack.png"];
imgPadLock.contentMode = UIViewContentModeCenter; // Don't stretch the UIImage in our UIImageView
// Add this new UIImageView in the UIView which contains our Delete button
UIView* parent = [confirmationButton superview];
[parent addSubview:imgPadLock];
}
});
}
Also, I needed to change the code which populates the UITableView, otherwise the "Delete" label would appear aswell as the padlock icon:
-(NSString*)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
Note* note = [listOfNotes objectAtIndex:indexPath.row];
if ( /* Is the user is allowed to delete this cell..? */ )
return @"Delete";
return @" ";
}
It's still ugly, and relies on assumptions that this won't all change when iOS 9 comes along.
This is the solution:
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Background"]];
[deleteButtonView addSubview:image];
}
}
}
IOS7 compatible answer (not creating a custom class, but extending the UITableViewCell :
@implementation UITableViewCell (customdelete)
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *subview in self.subviews) {
for(UIView *subview2 in subview.subviews){
if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
((UIView*)[subview2.subviews firstObject]).backgroundColor=COLOR_RED;
//YOU FOUND THE VIEW, DO WHATEVER YOU WANT, I JUST RECOLOURED IT
}
}
}
}
@end
来源:https://stackoverflow.com/questions/12130856/changing-the-color-of-uitableviewcelldeleteconfirmationcontroldelete-button-in