可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 set custom font and color for that.
Thank you for help!
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default,
title: "Delete",
handler: {
(action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
println("Delete button clicked!")
})
deleteAction.backgroundColor = UIColor.redColor()
return [deleteAction]
}
回答1:
How to use a custom font?
It's pretty easy.
- Firstly, you need to include your custom font files to your project.
- Next, go to your info.plist file and add a new entry with the key "Fonts provided by application". Note that this entry should be an Array.
- Then add the names of these files as elements of this array.
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];
How to change the font color?
Even easier. All you need is
cell.textlabel.textcolor = UIColor.redColor()
Edit:
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.
回答2:
Well, the only way I've found to set a custom font is to use the appearanceWhenContainedIn
method of the UIAppearance
protocol. This method isn't yet available in Swift, so you have to do it in Objective-C.
I made a class method in a utility Objective-C class to set it up:
+ (void)setUpDeleteRowActionStyleForUserCell {
UIFont *font = [UIFont fontWithName:@"AvenirNext-Regular" size:19];
NSDictionary *attributes = @{NSFontAttributeName: font,
NSForegroundColorAttributeName: [UIColor whiteColor]};
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString: @"DELETE"
attributes: attributes];
/*
* We include UIView in the containment hierarchy because there is another button in UserCell that is a direct descendant of UserCell that we don't want this to affect.
*/
[[UIButton appearanceWhenContainedIn:[UIView class], [UserCell class], nil] setAttributedTitle: attributedTitle
forState: UIControlStateNormal];
}
This works, but it's definitely not ideal. If you don't include UIView in the containment hierarchy, then it ends up affecting the disclosure indicator as well (I didn't even realize the disclosure indicator was a UIButton subclass). Also, if you have a UIButton in your cell that is inside a subview in the cell, then that button will get affected by this solution as well.
Considering the complications, it might be better to just use one of the more customizable open source libraries out there for table cell swipe options.
回答3:
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.
回答4:
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
}
}
}
}
回答5:
This seems to work, at least for setting the font color:
- (void)setupRowActionStyleForTableViewSwipes {
UIButton *appearanceButton = [UIButton appearanceWhenContainedInInstancesOfClasses:@[[NSClassFromString(@"UITableViewCellDeleteConfirmationView") class]]];
[appearanceButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
}
回答6:
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.
回答7:
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.
回答8:
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.
回答9:
//The following code is in Swift3.1
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let rejectAction = TableViewRowAction(style: UITableViewRowActionStyle.default, title: "\u{2715}\nReject") { action, indexPath in
print("didtapReject")
}
rejectAction.backgroundColor = UIColor.gray
let approveAction = TableViewRowAction(style: UITableViewRowActionStyle.default, title: "\u{2713}\nApprove") { action, indexPath in
print("didtapApprove")
}
approveAction.backgroundColor = UIColor.orange
return [rejectAction, approveAction]
}