在iOS的表格视图单元格中更改披露指标附件视图的颜色/视图的最佳方法是什么?

我需要更改UITableViewCell中的disclosureIndicatorView附件的颜色。 我认为有两种方法可以完成这个任务,但我无法弄清楚哪一个是最佳的。 所以这是我想我可以做的。

有一个属性UITableViewCellaccessoryView 。 所以我可以使用setAccessoryView:(UIView *)view和传递视图作为UIImageView持有我想要的图像。

我已经写了一个实用工具类,它为我的单元格创build了内容视图(像背景颜色,添加其他东西等),并将此内容视图添加到UITableViewDelegate的单元格。 另一个select是绘制一个UIImage覆盖CustomContentView工具类的drawRect方法。

执行选项1 – 我可以通过苹果的方式完成任务。 只要给他们看,他们就做剩下的事情。 但是,我想添加一个新的UIView对象到每一行可能会变成一个沉重的对象分配和降低帧速率。 与我的contentViewUIImage对象相比。 我相信UIImageUIView更轻。

请抛出一些轻的人,帮助我决定。

但是,我想添加一个新的UIView对象到每一行可能会变成一个笨重的obj分配和降低帧率。 与我的contentView中的UIImage对象相比。 我相信UIImage比UIView更轻。

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

解决这个问题的cocoa的伟大的post。 UIControl类inheritance了选定,启用和突出显示的“ 自定义彩色披露指标 ”属性

如果你对绘制指标感兴趣,而不是使用图像文件,下面是我devise的代码:

 // (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, xR, yR); CGContextAddLineToPoint(ctxt, x, y); CGContextAddLineToPoint(ctxt, xR, 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:方法中执行上面的操作,并将其作为你的附件视图,你可以使任何你想要的颜色。

附件视图(自定义或UIImageView将不会是一个主要的性能问题,只要您正确地回收UITableViewCell实例。

看一个图书馆。 很容易改变各种accessoryType的颜色。

MSCellAccessoryView

这是一个适用于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 

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

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

在迅速的3中,我已经将@galambalazs的解决scheme作为课程延伸进行了调整,如下所示:

 import UIKit extension UITableViewCell { func setDisclosure(toColour: UIColor) -> () { for view in self.subviews { if let disclosure = view as? UIButton { if let image = disclosure.backgroundImage(for: .normal) { let colouredImage = image.withRenderingMode(.alwaysTemplate); disclosure.setImage(colouredImage, for: .normal) disclosure.tintColor = toColour } } } } } 

希望这有助于一些。

benzado的解决scheme工作正常,但它显示了一个黑色的背景。 在你设置的UIView类中(你把代码放在drawRect函数中的那个类)需要具有下面的initWithFrame实现,以使得披露图有一个透明的背景:

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

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

虽然galambalazs的答案是有效的,但应该指出的是,它间接地访问和更新了苹果私人实施披露指标的方法,这是有些黑客。 在最好的情况下,它可能会停止在未来的iOS版本,最坏的情况下导致App Store拒绝。 在Apple公开一个属性直接设置颜色之前,设置accessoryView仍然是被批准的方法。

无论如何,这里是斯威夫特对于那些可能需要它的人的回答:

注意: cell.disclosureIndicatorColor必须 cell.accessoryType = .DisclosureIndicator设置 cell.accessoryType = .DisclosureIndicator在单元格的子视图中使用。

 extension UITableViewCell { public var disclosureIndicatorColor: UIColor? { get { return arrowButton?.tintColor } set { var image = arrowButton?.backgroundImageForState(.Normal) image = image?.imageWithRenderingMode(.AlwaysTemplate) arrowButton?.tintColor = newValue arrowButton?.setBackgroundImage(image, forState: .Normal) } } public func updateDisclosureIndicatorColorToTintColor() { self.disclosureIndicatorColor = self.window?.tintColor } private var arrowButton: UIButton? { var buttonView: UIButton? self.subviews.forEach { (view) in if view is UIButton { buttonView = view as? UIButton return } } return buttonView } } 

作为对@benzado解决scheme的一个贡献,我把他的代码swift化为:

 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); } 

随着应用程序颜色的改变,对UITableCellView上的setNeedsDisplay()的调用将更新颜色。 我喜欢避免在单元格视图中使用UIImage对象。

CocoaNetics 解决scheme的一个迅速3版本

 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() } } } 
Interesting Posts