「editActionsForRowAtIndexPath」メソッドでUITableViewRowActionを使用しています。 UITableViewRowActionの背景色を変更できますが、タイトルの色を変更できません。しかし、UITableViewRowActionの色を変更したいと思います。この点についてのあらゆるインプットは認められます。
UITableViewRowActionのタイトルの色を変更する方法はないと思います。
アクションで変更できる唯一のものは次のとおりです。
詳細については、 Apple Doc UITableViewRowAction を参照してください。
あなたが探しているものを達成することができる一つの方法があります。しかし、それは少しトリッキーです。
結果の例:
このトリックのアイデアは、実際に背景色を変更できるということです。これは、UIColorの+ colorWithPatternImage:を設定し、目的のスタイルに一致するビットマップ画像を設定できることを意味します。これは、グラフィックエディターを使用してイメージを作成するか、たとえばCore Graphicsを使用してレンダリングすることによって実現できます。このソリューションの唯一の問題は、適切に機能させるために特定のテキスト属性で元のタイトルの長さを模倣する必要があることと、テーブルビューのセルが十分に準備できるように、テーブルビュー行アクションのタイトルを空白の文字列として設定する必要があることです。あなたのためのスペース「カスタムアクションボタン」。可変セル行を使用する場合、Photoshopで静的PNGアセットを作成することは不適切な場合があります。
これは、カスタムボタン用のスペースを作成する空のスペースの文字列を作成するNSStringのカテゴリです。次に、背景パターン画像として配置されるビットマップ画像を生成します。パラメータの場合、元のタイトルのテキスト属性を設定する必要があります。つまり、基本的には@{NSFontAttributeName: [UIFont systemFontOfSize:18]}
、希望するテキスト属性よりも。多分これを達成するためのより良い方法があります:)
@implementation NSString (WhiteSpace)
- (NSString *)whitespaceReplacementWithSystemAttributes:(NSDictionary *)systemAttributes newAttributes:(NSDictionary *)newAttributes
{
NSString *stringTitle = self;
NSMutableString *stringTitleWS = [[NSMutableString alloc] initWithString:@""];
CGFloat diff = 0;
CGSize stringTitleSize = [stringTitle sizeWithAttributes:newAttributes];
CGSize stringTitleWSSize;
NSDictionary *originalAttributes = systemAttributes;
do {
[stringTitleWS appendString:@" "];
stringTitleWSSize = [stringTitleWS sizeWithAttributes:originalAttributes];
diff = (stringTitleSize.width - stringTitleWSSize.width);
if (diff <= 1.5) {
break;
}
}
while (diff > 0);
return [stringTitleWS copy];
}
@end
2番目の重要な部分は、UITableViewRowActionのbackgroundColorのパターンイメージとして使用できるビットマップをレンダリングするコードです。
- (UIImage *)imageForTableViewRowActionWithTitle:(NSString *)title textAttributes:(NSDictionary *)attributes backgroundColor:(UIColor *)color cellHeight:(CGFloat)cellHeight
{
NSString *titleString = title;
NSDictionary *originalAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:18]};
CGSize originalSize = [titleString sizeWithAttributes:originalAttributes];
CGSize newSize = CGSizeMake(originalSize.width + kSystemTextPadding + kSystemTextPadding, originalSize.height);
CGRect drawingRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, cellHeight));
UIGraphicsBeginImageContextWithOptions(drawingRect.size, YES, [UIScreen mainScreen].nativeScale);
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef, drawingRect);
UILabel *label = [[UILabel alloc] initWithFrame:drawingRect];
label.textAlignment = NSTextAlignmentCenter;
label.attributedText = [[NSAttributedString alloc] initWithString:title attributes:attributes];
[label drawTextInRect:drawingRect];
//This is other way how to render string
// CGSize size = [titleString sizeWithAttributes:attributes];
// CGFloat x = (drawingRect.size.width - size.width)/2;
// CGFloat y = (drawingRect.size.height - size.height)/2;
// drawingRect.Origin = CGPointMake(x, y);
// [titleString drawInRect:drawingRect withAttributes:attributes];
UIImage *returningImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returningImage;
}
そして、行アクションを作成するときに、次のようなことができます。
NSDictionary *systemAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:18] };
NSDictionary *newAttributes = @{NSFontAttributeName: [UIFont fontWithName:@"Any font" size:15]};
NSString *actionTitle = @"Delete";
NSString *titleWhiteSpaced = [actionTitle whitespaceReplacementWithSystemAttributes:systemTextFontAttributes newAttributes:newAttributes];
UITableViewRowAction *rowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleWhiteSpaced handle:NULL];
UIImage *patternImage = [self imageForTableViewRowActionWithTitle:actionTitle textAttributes:newAttributes backgroundColor:[UIColor redColor] cellHeight:50];
rowAction.backgroundColor = [UIColor colorWithPatternImage:patternImage];
このソリューションは明らかにハッキーですが、プライベートAPIを使用せずに目的の結果を得ることができ、将来、何かが壊れてもアプリは壊れません。ボタンのみが不適切に見えます。
結果の例:
もちろん、このコードには改善のためのスペースがたくさんあります。提案はありがたいです。
Swift
UIButton.appearanceをいじる必要はありません...
これをセルのクラスに配置し、必要に応じてUITableViewCellActionButtonを変更します。
override func layoutSubviews() {
super.layoutSubviews()
for subview in self.subviews {
for subview2 in subview.subviews {
if (String(subview2).rangeOfString("UITableViewCellActionButton") != nil) {
for view in subview2.subviews {
if (String(view).rangeOfString("UIButtonLabel") != nil) {
if let label = view as? UILabel {
label.textColor = YOUR COLOUR
}
}
}
}
}
}
}
Lee Andrew's answer inSwift 3/Swift 4:
class MyCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
for subview in self.subviews {
for sub in subview.subviews {
if String(describing: sub).range(of: "UITableViewCellActionButton") != nil {
for view in sub.subviews {
if String(describing: view).range(of: "UIButtonLabel") != nil {
if let label = view as? UILabel {
label.textColor = UIColor.black
}
}
}
}
}
}
}
}
実際、UITableViewRowActionのタイトルの色を変更する方法があります。ボタンです。 UIButton
外観プロキシを使用できます。
[[UIButton appearance] setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
iOS 11ソリューション:
次のようにUITableViewCell
拡張を作成します。
extension UITableViewCell {
/// Returns label of cell action button.
///
/// Use this property to set cell action button label color.
var cellActionButtonLabel: UILabel? {
for subview in self.superview?.subviews ?? [] {
if String(describing: subview).range(of: "UISwipeActionPullView") != nil {
for view in subview.subviews {
if String(describing: view).range(of: "UISwipeActionStandardButton") != nil {
for sub in view.subviews {
if let label = sub as? UILabel {
return label
}
}
}
}
}
}
return nil
}
}
そしてあなたのUITableViewCell
にこれを書いてください
override func layoutSubviews() {
super.layoutSubviews()
cellActionButtonLabel?.textColor = .red
}
しかし、バグがあります-セルを速く引っ張ると、このコードは色を変更しないことがあります。
これら2つの関数をUITableViewCell
サブクラスに追加し、setActionButtonsTitleColor
関数を呼び出してアクションボタンのタイトルの色を設定できます。
func setActionButtonsTitleColor(color: UIColor) {
let actionButtons: [UIButton] = self.getActionButtons()
for actionButton in actionButtons {
actionButton.setTitleColor(color, for: .normal)
}
}
func getActionButtons() -> [UIButton] {
let actionButtons: [UIButton] = self.subviews.map {
(view: UIView) -> [UIView] in
return view.subviews
}
.joined()
.filter {
(view: UIView) -> Bool in
return String(describing: view).contains("UITableViewCellActionButton")
}.flatMap {
(view: UIView) -> UIButton? in
return view as? UIButton
}
return actionButtons
}
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"edit" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Action something here
}];
editAction.backgroundColor = [UIColor whiteColor];
[[UIButton appearance] setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
return @[editAction];
誰かがまだ代替ソリューションを探している場合:
Swipecellkitポッドを使用できます
https://github.com/SwipeCellKit/SwipeCellKit
これにより、ネイティブ実装の実際のルックアンドフィールを維持しながら、ラベルの色、画像の色、さらには背景全体をカスタマイズできます。