问题
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!
回答1:
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.
回答2:
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
回答3:
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.)
回答4:
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.
回答5:
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];
}
}
}
回答6:
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