如何通过编程更改UITableView的披露指示器的颜色?

34

我知道可以使用 UIImageView 来设置 Disclosure Indicator Accessory,但我想在不使用 UIImageView 的情况下仅更改 disclosure indicator 颜色。

这是否可能?如果可能的话,该怎么做呢?


你的意思是什么?你总是可以使用自定义单元格。 - Raon
这是一个老问题,但至今没有令人满意的答案。以下是您实际所需的内容:http://stackoverflow.com/a/35427702/378024 - gblazex
6个回答

43

添加您自己的披露指示器:

cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"accessory.png"]];

1
谢谢回复,我知道这个,但是我想要在不使用UIImageView的情况下改变颜色,就像我们可以改变滑块的色调颜色一样。这可能吗? - Bhavesh
2
据我所知(不是很多),这似乎是不可能的。另一个可能性是,不使用 PNG,而是绘制指示器。请尝试使用此链接:http://www.cocoanetics.com/2010/10/custom-colored-disclosure-indicators/。 - RFG
可以实现。请查看我的回答,了解如何给原始的苹果指示器上色:http://stackoverflow.com/a/35427702/378024(不使用自定义图像或自定义绘图代码)。 - gblazex
http://www.cocoanetics.com/2010/10/custom-colored-disclosure-indicators/ 对我很有用...非常感谢RFG - Hari Narayanan
2
@galambalazs 您的答案非常好,但请将链接更正为 https://dev59.com/0nI-5IYBdhLWcg3wcn3m#35427599。 - Jamie McDaniel

4

我知道我来晚了,但我刚刚准备了一个自定义视图,绘制了一个披露视图。我为演示快速制作了它,所以可能不是非常精确,但它能完成工作。希望能对某些人有所帮助:

PZDisclosureIndicator.h

//
// Created by Pall Zoltan on 10/10/14.
// Copyright (c) 2014 pallzoltan. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface PZDisclosureIndicator : UIView
@property(nonatomic, strong) UIColor *color;

- (PZDisclosureIndicator *)initWithColor:(UIColor *)color;
@end

PZDisclosureIndicator.m:

//
// Created by Pall Zoltan on 10/10/14.
// Copyright (c) 2014 pallzoltan. All rights reserved.
//

#import "PZDisclosureIndicator.h"

@interface PZDisclosureIndicator ()

@property(nonatomic) CGFloat red;
@property(nonatomic) CGFloat green;
@property(nonatomic) CGFloat blue;
@property(nonatomic) CGFloat alpha;

@end

@implementation PZDisclosureIndicator

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, self.red, self.green, self.blue, self.alpha);

    CGContextMoveToPoint(context, 4, 0);
    CGContextAddLineToPoint(context, 4, 0);
    CGContextAddLineToPoint(context, 16, 12);
    CGContextAddLineToPoint(context, 4, 24);
    CGContextAddLineToPoint(context, 0, 24 - 4);
    CGContextAddLineToPoint(context, 9, 12);
    CGContextAddLineToPoint(context, 0, 4);
    CGContextAddLineToPoint(context, 4, 0);
    CGContextFillPath(context);
}

- (PZDisclosureIndicator *)initWithColor:(UIColor *)color {
    self = [super initWithFrame:CGRectMake(0, 0, 16, 24)];
    self.backgroundColor = [UIColor clearColor];

    self.color = color;
    [self setNeedsDisplay];

    return self;
}

- (void)setColor:(UIColor *)color {
    _color = color;

    [self.color getRed:&_red green:&_green blue:&_blue alpha:&_alpha];

    [self setNeedsDisplay];
}

@end

然后在我的自定义单元格中,我这样做:
self.accessoryView = [[PZDisclosureIndicator alloc] initWithColor:SECONDARY_HIGHLIGHT_COLOR];

理论上,您应该能够在初始化后更改它的颜色,但我没有尝试过。
看起来是这样的: 视图的实例使用示例 Z.

谢谢,这很好用!我稍微改了一下图纸,因为视图太大,线条太粗了,不符合我的需求,除此之外,对我来说完美无缺。 - Andra Todorescu
你能加入一张图片吗?谢谢。 - testing
或者在Swift中:http://pastebin.com/xgReAeWc - vrwim
运行良好,但我同意@AndraTodorescu的看法,箭头有点太粗了,不适合iOS 7+的美学。我修改了这个示例中的CGContextSetLineWidth(ctxt, 2);将其改为2而不是4,以获得所需的结果。 - Ryan Brodie

3
抱歉,我来晚了,但我今天遇到了这个问题并解决了它(在iOS8和9中)。使用View Debugger,很明显披露三角形是一个UIImage,位于UIButton中的UIImageView中。
因此,在-awakeFromNib中,我正在遍历子视图以查找按钮。一旦找到按钮,可以通过-backgroundImageForState:获得对原始图像的引用:
一旦获取到原始图像,您可以创建一个模板图像的副本,方法是调用[originalImage imageWithRenderingMode:AlwaysTemplate]
然后,您可以为所有可用状态设置backgroundImage。一旦这样做,图像会自动拾取色调颜色。
以下是一些Swift示例代码:
class GratuitousDisclosureTableViewCell: UITableViewCell {

    private weak var disclosureButton: UIButton? {
        didSet {
            if let originalImage = self.disclosureButton?.backgroundImageForState(.Normal) {
                let templateImage = originalImage.imageWithRenderingMode(.AlwaysTemplate)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Normal)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Highlighted)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Disabled)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Selected)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Application)
                self.disclosureButton?.setBackgroundImage(templateImage, forState: .Reserved)
            }
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        for view in self.subviews {
            if let button = view as? UIButton {
                self.disclosureButton = button
                break
            }
        }  
    }
}

1
哦,我应该补充说明,只要您的单元格视图层次结构中没有其他按钮,这将起作用。如果有,您需要为它们提供一个区分标签或其他东西,以便在查找正确的按钮时忽略它们。 - Jeffrey Bergier
awakeFromNib 中添加 self.tintColor = .red,然后再遍历 subViews,我认为这个子类会更清晰一些。 - Daniel Storm

1

您需要创建自己的自定义UIButton并将其设置为单元格的accessoryView。您不能仅通过指定其UIColor来更改其颜色。

您可以通过添加一张用于正常状态和另一张用于选中(高亮)状态的图像来自定义披露指示器。

一个用于自定义披露指示器的库:在这里查看


1
如上所述,修改accessoryView的一种方法是添加自己的UIImageView。但实际上,您可以提供任何派生自UIView的对象。然后,我建议使用带有图标字体(例如icomoon)的UILabel而不是UIImageView。 UILabel和图标字体允许在图像,颜色和大小方面具有灵活性。
let font = UIFont(name: "icomoon", size: 16.0)
let icon = "\u{e60f}"    
let lbl = UILabel(frame: CGRectMake(0, 0, 20, 20))
lbl.font = font
lbl.text = icon
cell.accessoryView = lbl

1
不起作用。图标显示为一个方框中的问号。不过这个想法很好。 - João Nunes
@JoãoNunes 你把 icomoon 添加到项目中了吗? - MÖRK
@MarkBlythe 不是的。如果我们需要那个,答案中就会提到它。 - João Nunes
@JoãoNunes 这里写着:UIFont(name: "icomoon"。至少有几个人会认识到这不是 iOS 默认嵌入的字体。 - njzk2
3
@njzk2 显然并非全部 - João Nunes
显示剩余2条评论

0
您可以尝试使用uiimageview来应用单元格accessoryType,如下所示的代码:
cell.accessoryView = myAccessoryUIImageView;
cell accessoryview uiimageview not align correctly try below code:


UIView* accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 50)];
UIImageView* accessoryViewImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"accessory_image.png"]];
accessoryViewImage.center = CGPointMake(12, 25);
[accessoryView addSubview:accessoryViewImage];
[cell setAccessoryView:accessoryView];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接