I have classic TableView where you can delete item if you swipe and than clicking on the button. I know how to set custom background on the cell, but I can\'t find how I can
I want to share my solution for ObjC, this is just a trick but works as expected for me.
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
// this just convert view to `UIImage`
UIImage *(^imageWithView)(UIView *) = ^(UIView *view) {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
};
// This is where the magic happen,
// The width and height must be dynamic (it's up to you how to implement it)
// to keep the alignment of the label in place
//
UIColor *(^getColorWithLabelText)(NSString*, UIColor*, UIColor*) = ^(NSString *text, UIColor *textColor, UIColor *bgColor) {
UILabel *lbDelete = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 47, 40)];
lbDelete.font = [UIFont boldSystemFontOfSize:11];
lbDelete.text = text;
lbDelete.textAlignment = NSTextAlignmentCenter;
lbDelete.textColor = textColor;
lbDelete.backgroundColor = bgColor;
return [UIColor colorWithPatternImage:imageWithView(lbDelete)];
};
// The `title` which is `@" "` is important it
// gives you the space you needed for the
// custom label `47[estimated width], 40[cell height]` on this example
//
UITableViewRowAction *btDelete;
btDelete = [UITableViewRowAction
rowActionWithStyle:UITableViewRowActionStyleDestructive
title:@" "
handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"Delete");
[tableView setEditing:NO];
}];
// Implementation
//
btDelete.backgroundColor = getColorWithLabelText(@"Delete", [UIColor whiteColor], [YJColor colorWithHexString:@"fe0a09"]);
UITableViewRowAction *btMore;
btMore = [UITableViewRowAction
rowActionWithStyle:UITableViewRowActionStyleNormal
title:@" "
handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
NSLog(@"More");
[tableView setEditing:NO];
}];
// Implementation
//
btMore.backgroundColor = getColorWithLabelText(@"More", [UIColor darkGrayColor], [YJColor colorWithHexString:@"46aae8"]);
return @[btMore, btDelete];
}
[YJColor colorWithHexString:<NSString>];
is just to convert hex string to UIColor.
Check the example output screenshot.
It's pretty easy.
And that's it! All you need then is to use the font by its name like this
cell.textLabel.font = [UIFont fontWithName:@"FontName" size:16];
Even easier. All you need is
cell.textlabel.textcolor = UIColor.redColor()
In your case you want to change the font of the RowAction. So I think of only 2 solutions. One to use [UIColor colorWithPatterImage:]
Or you can user [[UIButton appearance] setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
because the RowAction contains a button.
I think you can use this method to change the appearance only in one (or more, you can define it) viewcontrollers:
//create your attributes however you want to
let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(UIFont.systemFontSize())] as Dictionary!
//Add more view controller types in the []
UIButton.appearanceWhenContainedInInstancesOfClasses([ViewController.self])
Hope this helped.
Here is some Swift Code that might be helpful:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) ->[AnyObject]? {
let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(UIFont.systemFontSize())] as Dictionary!
UIButton.appearance().setAttributedTitle(NSAttributedString(string: "Your Button", attributes: attributes), forState: .Normal)
// Things you do...
}
This will manipulate all buttons in your application.
If you use XCode's Debug View Hierarchy to look what is happening in UITableView when the swipe buttons are active, you'll see that UITableViewRowAction items translates to button called _UITableViewCellActionButton
, contained in UITableViewCellDeleteConfirmationView
. One way to change button's properties is to intercept it when it's added to UITableViewCell
. In your UITableViewCell
derived class write something like this:
private let buttonFont = UIFont.boldSystemFontOfSize(13)
private let confirmationClass: AnyClass = NSClassFromString("UITableViewCellDeleteConfirmationView")!
override func addSubview(view: UIView) {
super.addSubview(view)
// replace default font in swipe buttons
let s = subviews.flatMap({$0}).filter { $0.isKindOfClass(confirmationClass) }
for sub in s {
for button in sub.subviews {
if let b = button as? UIButton {
b.titleLabel?.font = buttonFont
}
}
}
}
You could use UIButton.appearance
to style the button inside the row action. Like so:
let buttonStyle = UIButton.appearance(whenContainedInInstancesOf: [YourViewController.self])
let font = UIFont(name: "Custom-Font-Name", size: 16.0)!
let string = NSAttributedString(string: "BUTTON TITLE", attributes: [NSAttributedString.Key.font : font, NSAttributedString.Key.foregroundColor : UIColor.green])
buttonStyle.setAttributedTitle(string, for: .normal)
Note: this will affect all of your buttons in this view controller.