如何在没有情节提要的情况下在 UITableViewRowAction 中自定义字体和颜色
How to do custom font and color in UITableViewRowAction without Storyboard
我有经典的 TableView,如果你滑动然后点击按钮,你可以删除项目。我知道如何在单元格上设置自定义背景,但我找不到如何为其设置自定义字体和颜色。
感谢您的帮助!
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]
}
如何使用自定义字体?
很简单。
- 首先,您需要将自定义字体文件包含到您的项目中。
- 接下来,转到您的 info.plist 文件并使用关键字“Fonts provided by application”添加一个新条目。请注意,此条目应该是一个数组。
- 然后将这些文件的名称添加为该数组的元素。
就是这样!您所需要的就是像这样按名称使用字体
cell.textLabel.font = [UIFont fontWithName:@"FontName" size:16];
如何更改字体颜色?
更简单。您只需要
cell.textlabel.textcolor = UIColor.redColor()
编辑:
在您的情况下,您想更改 RowAction 的字体。所以我只想到2个解决方案。一个使用[UIColor colorWithPatterImage:]
或者您可以使用 [[UIButton appearance] setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
,因为 RowAction 包含一个按钮。
好吧,我发现设置自定义字体的唯一方法是使用 UIAppearance
协议的 appearanceWhenContainedIn
方法。此方法在 Swift 中尚不可用,因此您必须在 Objective-C.
中使用
我在实用程序 Objective-C class 中创建了一个 class 方法来设置它:
+ (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];
}
这可行,但绝对不理想。如果您不在包含层次结构中包含 UIView,那么它最终也会影响披露指示器(我什至没有意识到披露指示器是一个 UIButton subclass)。此外,如果您的单元格中有一个 UIButton,它位于单元格的子视图内,那么该按钮也会受到此解决方案的影响。
考虑到复杂性,最好只使用一种更可定制的开源库来实现 table 单元格滑动选项。
下面是一些可能有用的 Swift 代码:
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...
}
这将操作您应用程序中的所有按钮。
我认为您可以使用此方法仅在一个(或多个,您可以定义)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])
希望对您有所帮助。
这似乎可行,至少对于设置字体颜色而言:
- (void)setupRowActionStyleForTableViewSwipes {
UIButton *appearanceButton = [UIButton appearanceWhenContainedInInstancesOfClasses:@[[NSClassFromString(@"UITableViewCellDeleteConfirmationView") class]]];
[appearanceButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
}
如果您使用 XCode 的调试视图层次结构查看滑动按钮处于活动状态时 UITableView 中发生的情况,您会看到 UITableViewRowAction 项目转换为名为 _UITableViewCellActionButton
的按钮,包含在 UITableViewCellDeleteConfirmationView
。更改按钮属性的一种方法是在将其添加到 UITableViewCell
时拦截它。在你的 UITableViewCell
派生 class 中写这样的东西:
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({[=10=]}).filter { [=10=].isKindOfClass(confirmationClass) }
for sub in s {
for button in sub.subviews {
if let b = button as? UIButton {
b.titleLabel?.font = buttonFont
}
}
}
}
我想分享我对 ObjC 的解决方案,这只是一个技巧,但对我来说效果很好。
- (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>];
只是将十六进制字符串转换为UIColor。
查看示例输出屏幕截图。
//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]
}
您可以使用 UIButton.appearance
在行操作中设置按钮的样式。像这样:
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)
注意:这将影响此视图控制器中的所有按钮。
我有经典的 TableView,如果你滑动然后点击按钮,你可以删除项目。我知道如何在单元格上设置自定义背景,但我找不到如何为其设置自定义字体和颜色。
感谢您的帮助!
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]
}
如何使用自定义字体?
很简单。
- 首先,您需要将自定义字体文件包含到您的项目中。
- 接下来,转到您的 info.plist 文件并使用关键字“Fonts provided by application”添加一个新条目。请注意,此条目应该是一个数组。
- 然后将这些文件的名称添加为该数组的元素。
就是这样!您所需要的就是像这样按名称使用字体
cell.textLabel.font = [UIFont fontWithName:@"FontName" size:16];
如何更改字体颜色?
更简单。您只需要
cell.textlabel.textcolor = UIColor.redColor()
编辑:
在您的情况下,您想更改 RowAction 的字体。所以我只想到2个解决方案。一个使用[UIColor colorWithPatterImage:]
或者您可以使用 [[UIButton appearance] setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
,因为 RowAction 包含一个按钮。
好吧,我发现设置自定义字体的唯一方法是使用 UIAppearance
协议的 appearanceWhenContainedIn
方法。此方法在 Swift 中尚不可用,因此您必须在 Objective-C.
我在实用程序 Objective-C class 中创建了一个 class 方法来设置它:
+ (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];
}
这可行,但绝对不理想。如果您不在包含层次结构中包含 UIView,那么它最终也会影响披露指示器(我什至没有意识到披露指示器是一个 UIButton subclass)。此外,如果您的单元格中有一个 UIButton,它位于单元格的子视图内,那么该按钮也会受到此解决方案的影响。
考虑到复杂性,最好只使用一种更可定制的开源库来实现 table 单元格滑动选项。
下面是一些可能有用的 Swift 代码:
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...
}
这将操作您应用程序中的所有按钮。
我认为您可以使用此方法仅在一个(或多个,您可以定义)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])
希望对您有所帮助。
这似乎可行,至少对于设置字体颜色而言:
- (void)setupRowActionStyleForTableViewSwipes {
UIButton *appearanceButton = [UIButton appearanceWhenContainedInInstancesOfClasses:@[[NSClassFromString(@"UITableViewCellDeleteConfirmationView") class]]];
[appearanceButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
}
如果您使用 XCode 的调试视图层次结构查看滑动按钮处于活动状态时 UITableView 中发生的情况,您会看到 UITableViewRowAction 项目转换为名为 _UITableViewCellActionButton
的按钮,包含在 UITableViewCellDeleteConfirmationView
。更改按钮属性的一种方法是在将其添加到 UITableViewCell
时拦截它。在你的 UITableViewCell
派生 class 中写这样的东西:
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({[=10=]}).filter { [=10=].isKindOfClass(confirmationClass) }
for sub in s {
for button in sub.subviews {
if let b = button as? UIButton {
b.titleLabel?.font = buttonFont
}
}
}
}
我想分享我对 ObjC 的解决方案,这只是一个技巧,但对我来说效果很好。
- (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>];
只是将十六进制字符串转换为UIColor。
查看示例输出屏幕截图。
//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]
}
您可以使用 UIButton.appearance
在行操作中设置按钮的样式。像这样:
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)
注意:这将影响此视图控制器中的所有按钮。