哪个是在iOS中的表格视图单元格中更改公开指示器附件视图的颜色/视图的最佳方法?

时间:2009-12-05 16:39:56

标签: ios uitableview indicator accessory

我需要更改disclosureIndicatorViewUITableViewCell附件的颜色。 我认为有两种方法可以完成这项任务,但我无法弄清楚哪一种是最佳选择。所以这就是我认为我能做到的。

UITableViewCell - accessoryView的属性。所以我可以使用setAccessoryView:(UIView *)view并将视图作为UIImageView传递给我想要的图像。

我编写了一个实用程序类,它为我的单元格创建内容视图(像背景颜色,添加其他东西等等),然后将此内容视图添加到UITableViewDelegate中的单元格中。另一种选择是绘制UIImage覆盖drawRect实用程序类的CustomContentView方法。

执行选项1 - 我可以通过苹果方式完成工作。只要给他们观点,他们就会完成其余的工作。但我想在每一行添加一个新的UIView对象可能会成为一个繁重的对象分配并降低帧速率。与我UIImage中的contentView对象相比。我相信UIImageUIView轻。

请抛弃一些轻松的人并帮我决定。

12 个答案:

答案 0 :(得分:29)

关于Cocoanetics的伟大帖子解决了这个问题。 UIControl类继承选定,启用和突出显示的属性Custom-Colored Disclosure Indicators

答案 1 :(得分:24)

如果您对绘制指标感兴趣,而不是使用图像文件,请参考以下代码:

// (x,y) is the tip of the arrow
CGFloat x = CGRectGetMaxX(self.bounds) - RIGHT_MARGIN;
CGFloat y = CGRectGetMidY(self.bounds);
const CGFloat R = 4.5;
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(ctxt, x-R, y-R);
CGContextAddLineToPoint(ctxt, x, y);
CGContextAddLineToPoint(ctxt, x-R, y+R);
CGContextSetLineCap(ctxt, kCGLineCapSquare);
CGContextSetLineJoin(ctxt, kCGLineJoinMiter);
CGContextSetLineWidth(ctxt, 3);
// If the cell is highlighted (blue background) draw in white; otherwise gray
if (CONTROL_IS_HIGHLIGHTED) {
    CGContextSetRGBStrokeColor(ctxt, 1, 1, 1, 1);
} else {
    CGContextSetRGBStrokeColor(ctxt, 0.5, 0.5, 0.5, 1);
}
CGContextStrokePath(ctxt);

如果您创建自定义UIView子类,请在drawRect:方法中执行上述操作,并将其用作附件视图,您将能够将颜色设置为您想要的颜色。

附件视图(只要您正确回收UITableViewCell实例,自定义或UIImageView就不会成为主要的性能问题。

答案 2 :(得分:9)

这是一个适用于iOS 8+的实现。 它完全符合以下要求:
将原始Apple披露指示器的颜色更改为自定义颜色。
 像这样使用它:

#import "UITableViewCell+DisclosureIndicatorColor.h"
// cell is a UITableViewCell
cell.disclosureIndicatorColor = [UIColor redColor]; // custom color
[cell updateDisclosureIndicatorColorToTintColor]; // or use global tint color

的UITableViewCell + DisclosureIndicatorColor.h

@interface UITableViewCell (DisclosureIndicatorColor)
@property (nonatomic, strong) UIColor *disclosureIndicatorColor;
- (void)updateDisclosureIndicatorColorToTintColor;
@end

的UITableViewCell + DisclosureIndicatorColor.m

@implementation UITableViewCell (DisclosureIndicatorColor)

- (void)updateDisclosureIndicatorColorToTintColor {
    [self setDisclosureIndicatorColor:self.window.tintColor];
}

- (void)setDisclosureIndicatorColor:(UIColor *)color {
    NSAssert(self.accessoryType == UITableViewCellAccessoryDisclosureIndicator,
        @"accessory type needs to be UITableViewCellAccessoryDisclosureIndicator");

    UIButton *arrowButton = [self arrowButton];
    UIImage *image = [arrowButton backgroundImageForState:UIControlStateNormal];
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    arrowButton.tintColor = color;
    [arrowButton setBackgroundImage:image forState:UIControlStateNormal];
}

- (UIColor *)disclosureIndicatorColor {
    NSAssert(self.accessoryType == UITableViewCellAccessoryDisclosureIndicator, 
        @"accessory type needs to be UITableViewCellAccessoryDisclosureIndicator");

    UIButton *arrowButton = [self arrowButton];
    return arrowButton.tintColor;
}

- (UIButton *)arrowButton {
    for (UIView *view in self.subviews)
        if ([view isKindOfClass:[UIButton class]])
            return (UIButton *)view;
    return nil;
}

@end

答案 3 :(得分:6)

在swift 3中,我已将@galambalazs的解决方案改编为类扩展,如下所示:

aC.commandText := 'SELECT [MODEL], [PART], [SECTION], [FOOTPRINT], [NODELIST] FROM BJT WHERE lower( BJT.MODEL ) LIKE ''m%'';';
aDS.resultSet := aC.execute;

希望这会有所帮助。

答案 4 :(得分:5)

使用UIImageView。这也允许您在选择单元格时更改图像:

UIImageView* arrowView = [[UIImageView alloc] initWithImage:normalImage];
arrowView.highlightedImage = selectedImage;
cell.accessoryView = arrowView;
[arrowView release];

答案 5 :(得分:4)

  

但我想在每一行添加一个新的UIView对象可能会成为一个重度的obj分配并降低帧速率。与我的contentView中的UIImage对象相比。我相信UIImage比UIView更轻。

直接绘制图像几乎肯定会比添加子视图具有更好的性能。您必须确定是否需要额外的性能。我已经在基本单元上使用了一些附件视图来定制披露指标,性能很好。但是,如果您已经为内容rect进行自定义绘图,那么也可能不那么难以进行附件视图。

答案 6 :(得分:2)

benzado的解决方案工作正常,但它显示黑色背景。在您设置的UIView类中(您在其代码中放置了drawRect函数的那个​​)需要具有以下initWithFrame实现,以便公开绘图具有透明背景:

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor clearColor]];
        // Initialization code.
    }
    return self;
}

当然,您可以将其设置为您想要的任何颜色......

答案 7 :(得分:1)

尽管galambalazs的回答有效,但值得注意的是,它间接访问并更新了Apple公开指标的私人实施,这有点像黑客攻击。充其量,它可能会在未来的iOS版本中停止工作,最糟糕的是导致App Store拒绝。在Apple公开直接设置颜色的属性之前,设置accessoryView仍然是经过批准的方法。

无论如何,Swift实现了他对那些可能需要它的人的回答:

注意:设置 cell.disclosureIndicatorColor后必须设置,以便在单元格的子视图中显示disclosureIndicator按钮:

cell.accessoryType = .DisclosureIndicator

答案 8 :(得分:1)

更改表格视图单元格的颜色。 检查屏幕截图以通过Storyboard进行相同操作。

答案 9 :(得分:1)

在iOS 13+中,公开指标是通过非模板化UIImage设置的,该模板由用户的暗模式首选项确定。由于图像是非模板的,因此将不遵守单元格的tintColor属性。换句话说,暗模式首选项具有最高优先级。如果您不想使用iOS派生的公开指示器,则必须使用自定义图片。

答案 10 :(得分:0)

作为对@benzado解决方案的贡献,我按照以下方式改进了他的代码:

override func drawRect(rect: CGRect) {

  super.drawRect(rect)

  let context = UIGraphicsGetCurrentContext();

  let right_margin : CGFloat = 15.0
  let length : CGFloat = 4.5;

  // (x,y) is the tip of the arrow
  let x = CGRectGetMaxX(self.bounds) - right_margin;
  let y = CGRectGetMidY(self.bounds);

  CGContextMoveToPoint(context, x - length, y - length);
  CGContextAddLineToPoint(context, x, y);
  CGContextAddLineToPoint(context, x - length, y + length);
  CGContextSetLineCap(context, .Round);
  CGContextSetLineJoin(context, .Miter);
  CGContextSetLineWidth(context, 2.5);

  if (self.highlighted)
  {
    CGContextSetStrokeColorWithColor(context, UIColor.appColorSelected().CGColor);
  }
  else
  {
    CGContextSetStrokeColorWithColor(context, UIColor.appColor().CGColor);
  }

  CGContextStrokePath(context);
}

通过更改app颜色,在UITableCellView上调用setNeedsDisplay()将更新颜色。我喜欢避免在单元格视图中使用UIImage对象。

答案 11 :(得分:0)

CocoaNetics的快速3版本solution

public class DisclosureIndicator: UIControl {

    public static func create(color: UIColor?, highlightedColor: UIColor?) -> DisclosureIndicator{
        let indicator = DisclosureIndicator(frame: CGRect(x: 0, y: 0, width: 11, height: 15))
        if let color = color { indicator.color = color }
        if let color = highlightedColor { indicator.highlightedColor = color }
        return indicator
    }

    public var color: UIColor = .black
    public var highlightedColor: UIColor = .white

    override public init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .clear
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        backgroundColor = .clear
    }

    override public func draw(_ rect: CGRect) {
        super.draw(rect)

        let context = UIGraphicsGetCurrentContext()!;

        // (x,y) is the tip of the arrow
        let x = self.bounds.maxX - 3.0;
        let y = self.bounds.midY;

        let length : CGFloat = 4.5;
        context.move(to: CGPoint(x: x - length, y: y - length))
        context.addLine(to: CGPoint(x: x, y: y))
        context.addLine(to: CGPoint(x: x - length, y: y + length))
        context.setLineCap(.round)
        context.setLineJoin(.miter)
        context.setLineWidth(3)

        context.setStrokeColor((isHighlighted ? highlightedColor : color).cgColor)

        context.strokePath()
    }

    override public var isHighlighted: Bool {
        get {
            return super.isHighlighted
        }
        set {
            super.isHighlighted = newValue
            setNeedsDisplay()
        }
    }
}