我已经通过以下方式自定义了背景颜色:
tableView.contentView.backgroundColor = [UIColor greenColor];
但是边框颜色仍然是我不知道如何更改的内容。
我该如何自定义分组样式表视图的这两个方面呢?
tableView.contentView.backgroundColor = [UIColor greenColor];
但是边框颜色仍然是我不知道如何更改的内容。
我该如何自定义分组样式表视图的这两个方面呢?
更新:在 iPhone OS 3.0 及之后的版本中,UITableViewCell
现在有一个 backgroundColor
属性,这使得这个变得非常容易(特别是与 [UIColor colorWithPatternImage:]
构造函数一起使用)。但是我将保留答案中的 2.0 版本,以供需要的人使用...
实现这个功能比它应该要困难。以下是我在必须这样做时所采用的方法:
您需要将 UITableViewCell 的 backgroundView 属性设置为一个自定义的 UIView,该视图会以适当的颜色绘制边框和背景。此视图需要能够以 4 种不同的模式绘制边框,在第一部分中顶部圆角,最后一个单元格为底部圆角,在部分中间没有圆角的单元格以及包含一个单元格的部分中的所有 4 个角都是圆角。
不幸的是,我无法找到如何自动设置此模式,因此我不得不在 UITableViewDataSource 的 -cellForRowAtIndexPath 方法中进行设置。
这真是让人头疼,但我已经与苹果工程师确认,这目前是唯一的方法。
更新 这是自定义背景视图的代码。存在一个绘制缺陷,使得圆角看起来有点奇怪,但是在我有机会修复它之前,我们已经更换了不同的设计并放弃了自定义背景。尽管如此,这仍然可能对您非常有帮助:
//
// CustomCellBackgroundView.h
//
// Created by Mike Akers on 11/21/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef enum {
CustomCellBackgroundViewPositionTop,
CustomCellBackgroundViewPositionMiddle,
CustomCellBackgroundViewPositionBottom,
CustomCellBackgroundViewPositionSingle
} CustomCellBackgroundViewPosition;
@interface CustomCellBackgroundView : UIView {
UIColor *borderColor;
UIColor *fillColor;
CustomCellBackgroundViewPosition position;
}
@property(nonatomic, retain) UIColor *borderColor, *fillColor;
@property(nonatomic) CustomCellBackgroundViewPosition position;
@end
//
// CustomCellBackgroundView.m
//
// Created by Mike Akers on 11/21/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "CustomCellBackgroundView.h"
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
float ovalWidth,float ovalHeight);
@implementation CustomCellBackgroundView
@synthesize borderColor, fillColor, position;
- (BOOL) isOpaque {
return NO;
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [fillColor CGColor]);
CGContextSetStrokeColorWithColor(c, [borderColor CGColor]);
if (position == CustomCellBackgroundViewPositionTop) {
CGContextFillRect(c, CGRectMake(0.0f, rect.size.height - 10.0f, rect.size.width, 10.0f));
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, rect.size.height - 10.0f);
CGContextAddLineToPoint(c, 0.0f, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height - 10.0f);
CGContextStrokePath(c);
CGContextClipToRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height - 10.0f));
} else if (position == CustomCellBackgroundViewPositionBottom) {
CGContextFillRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, 10.0f));
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, 10.0f);
CGContextAddLineToPoint(c, 0.0f, 0.0f);
CGContextStrokePath(c);
CGContextBeginPath(c);
CGContextMoveToPoint(c, rect.size.width, 0.0f);
CGContextAddLineToPoint(c, rect.size.width, 10.0f);
CGContextStrokePath(c);
CGContextClipToRect(c, CGRectMake(0.0f, 10.0f, rect.size.width, rect.size.height));
} else if (position == CustomCellBackgroundViewPositionMiddle) {
CGContextFillRect(c, rect);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, 0.0f);
CGContextAddLineToPoint(c, 0.0f, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, 0.0f);
CGContextStrokePath(c);
return; // no need to bother drawing rounded corners, so we return
}
// At this point the clip rect is set to only draw the appropriate
// corners, so we fill and stroke a rounded rect taking the entire rect
CGContextBeginPath(c);
addRoundedRectToPath(c, rect, 10.0f, 10.0f);
CGContextFillPath(c);
CGContextSetLineWidth(c, 1);
CGContextBeginPath(c);
addRoundedRectToPath(c, rect, 10.0f, 10.0f);
CGContextStrokePath(c);
}
- (void)dealloc {
[borderColor release];
[fillColor release];
[super dealloc];
}
@end
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
float ovalWidth,float ovalHeight)
{
float fw, fh;
if (ovalWidth == 0 || ovalHeight == 0) {// 1
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);// 2
CGContextTranslateCTM (context, CGRectGetMinX(rect),// 3
CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);// 4
fw = CGRectGetWidth (rect) / ovalWidth;// 5
fh = CGRectGetHeight (rect) / ovalHeight;// 6
CGContextMoveToPoint(context, fw, fh/2); // 7
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);// 8
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);// 9
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);// 10
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // 11
CGContextClosePath(context);// 12
CGContextRestoreGState(context);// 13
}
我知道答案涉及更改分组表格单元格,但如果有人还想更改表格视图的背景颜色:
不仅需要设置以下内容:
tableview.backgroundColor = color;
还需要改变或者去掉背景视图:
tableview.backgroundView = nil;
首先感谢这段代码。我对这个函数进行了一些绘图方面的更改,以解决绘制时出现的角落问题。
-(void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [fillColor CGColor]);
CGContextSetStrokeColorWithColor(c, [borderColor CGColor]);
CGContextSetLineWidth(c, 2);
if (position == CustomCellBackgroundViewPositionTop) {
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy ;
CGContextMoveToPoint(c, minx, maxy);
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, miny, maxx, maxy, ROUND_SIZE);
CGContextAddLineToPoint(c, maxx, maxy);
// Close the path
CGContextClosePath(c);
// Fill & stroke the path
CGContextDrawPath(c, kCGPathFillStroke);
return;
} else if (position == CustomCellBackgroundViewPositionBottom) {
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny ;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, miny);
CGContextAddArcToPoint(c, minx, maxy, midx, maxy, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, ROUND_SIZE);
CGContextAddLineToPoint(c, maxx, miny);
// Close the path
CGContextClosePath(c);
// Fill & stroke the path
CGContextDrawPath(c, kCGPathFillStroke);
return;
} else if (position == CustomCellBackgroundViewPositionMiddle) {
CGFloat minx = CGRectGetMinX(rect) , maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny ;
maxx = maxx - 1;
maxy = maxy ;
CGContextMoveToPoint(c, minx, miny);
CGContextAddLineToPoint(c, maxx, miny);
CGContextAddLineToPoint(c, maxx, maxy);
CGContextAddLineToPoint(c, minx, maxy);
CGContextClosePath(c);
// Fill & stroke the path
CGContextDrawPath(c, kCGPathFillStroke);
return;
}
}
谢谢你提供这段代码,正是我在寻找的。我还向Vimal的代码中添加了以下代码,以实现CustomCellBackgroundViewPositionSingle单元格的情况。(四个角都是圆角。)
else if (position == CustomCellBackgroundViewPositionSingle)
{
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , midy = CGRectGetMidY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, midy);
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, miny, maxx, midy, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, maxy, midx, maxy, ROUND_SIZE);
CGContextAddArcToPoint(c, minx, maxy, minx, midy, ROUND_SIZE);
// Close the path
CGContextClosePath(c);
// Fill & stroke the path
CGContextDrawPath(c, kCGPathFillStroke);
return;
}
在 Mike Akers 提供的 CustomCellBackgroundView 代码中,我遇到了一个问题,这可能对他人有用:
cell.backgroundView
在单元格被重用时不会自动重新绘制,而且对 backgroundView 的位置变量的更改也不会影响到重用的单元格。这意味着对于它们的位置,长表将具有不正确绘制的 cell.backgroundViews
。
为了修复这个问题,而不必每次显示行时都创建一个新的 backgroundView,请在你的 -[UITableViewController tableView:cellForRowAtIndexPath:]
的末尾调用 [cell.backgroundView setNeedsDisplay]
。或者,为了获得更可重用的解决方案,可以覆盖 CustomCellBackgroundView 的位置 setter 并包含一个 [self setNeedsDisplay]
。
非常感谢这篇超级有用的帖子。如果有人(像我一样!)想要完全空白的单元格背景,而不是通过在IB中自定义图像/文本/其他内容来进行定制,并且无法弄清楚如何消除愚蠢的边框/填充/背景,即使您在IB中将其设置为透明...这里是我使用的代码,解决了这个问题!
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
static NSString *cellId = @"cellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellId];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"EditTableViewCell" owner:self options:nil];
cell = cellIBOutlet;
self.cellIBOutlet = nil;
}
cell.backgroundView = [[[UIView alloc] initWithFrame: CGRectZero] autorelease];
[cell.backgroundView setNeedsDisplay];
... any other cell customizations ...
return cell;
}
希望这能对其他人有所帮助!看起来运行得很好。
cell.backgroundView
的视图。 - Cameron Spickert//
// CSCustomCellBackgroundView.h
//
#import <UIKit/UIKit.h>
typedef enum
{
CustomCellBackgroundViewPositionTop,
CustomCellBackgroundViewPositionMiddle,
CustomCellBackgroundViewPositionBottom,
CustomCellBackgroundViewPositionSingle,
CustomCellBackgroundViewPositionPlain
} CustomCellBackgroundViewPosition;
@interface CSCustomCellBackgroundView : UIView
{
CustomCellBackgroundViewPosition position;
CGGradientRef gradient;
}
@property(nonatomic) CustomCellBackgroundViewPosition position;
@end
//
// CSCustomCellBackgroundView.m
//
#import "CSCustomCellBackgroundView.h"
#define ROUND_SIZE 10
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
float ovalWidth,float ovalHeight);
@implementation CSCustomCellBackgroundView
@synthesize position;
- (BOOL) isOpaque
{
return NO;
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
// Initialization code
const float* topCol = CGColorGetComponents([[UIColor redColor] CGColor]);
const float* bottomCol = CGColorGetComponents([[UIColor blueColor] CGColor]);
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
/*
CGFloat colors[] =
{
5.0 / 255.0, 140.0 / 255.0, 245.0 / 255.0, 1.00,
1.0 / 255.0, 93.0 / 255.0, 230.0 / 255.0, 1.00,
};*/
CGFloat colors[]=
{
topCol[0], topCol[1], topCol[2], topCol[3],
bottomCol[0], bottomCol[1], bottomCol[2], bottomCol[3]
};
gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));
CGColorSpaceRelease(rgb);
}
return self;
}
-(void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef c = UIGraphicsGetCurrentContext();
if (position == CustomCellBackgroundViewPositionTop)
{
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy ;
CGContextMoveToPoint(c, minx, maxy);
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, miny, maxx, maxy, ROUND_SIZE);
CGContextAddLineToPoint(c, maxx, maxy);
// Close the path
CGContextClosePath(c);
CGContextSaveGState(c);
CGContextClip(c);
CGContextDrawLinearGradient(c, gradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(c);
return;
}
else if (position == CustomCellBackgroundViewPositionBottom)
{
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, miny);
CGContextAddArcToPoint(c, minx, maxy, midx, maxy, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, ROUND_SIZE);
CGContextAddLineToPoint(c, maxx, miny);
// Close the path
CGContextClosePath(c);
CGContextSaveGState(c);
CGContextClip(c);
CGContextDrawLinearGradient(c, gradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(c);
return;
}
else if (position == CustomCellBackgroundViewPositionMiddle)
{
CGFloat minx = CGRectGetMinX(rect) , maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy ;
CGContextMoveToPoint(c, minx, miny);
CGContextAddLineToPoint(c, maxx, miny);
CGContextAddLineToPoint(c, maxx, maxy);
CGContextAddLineToPoint(c, minx, maxy);
// Close the path
CGContextClosePath(c);
CGContextSaveGState(c);
CGContextClip(c);
CGContextDrawLinearGradient(c, gradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(c);
return;
}
else if (position == CustomCellBackgroundViewPositionSingle)
{
CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
CGFloat miny = CGRectGetMinY(rect) , midy = CGRectGetMidY(rect) , maxy = CGRectGetMaxY(rect) ;
minx = minx + 1;
miny = miny + 1;
maxx = maxx - 1;
maxy = maxy - 1;
CGContextMoveToPoint(c, minx, midy);
CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, miny, maxx, midy, ROUND_SIZE);
CGContextAddArcToPoint(c, maxx, maxy, midx, maxy, ROUND_SIZE);
CGContextAddArcToPoint(c, minx, maxy, minx, midy, ROUND_SIZE);
// Close the path
CGContextClosePath(c);
CGContextSaveGState(c);
CGContextClip(c);
CGContextDrawLinearGradient(c, gradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(c);
return;
}
else if (position == CustomCellBackgroundViewPositionPlain) {
CGFloat minx = CGRectGetMinX(rect);
CGFloat miny = CGRectGetMinY(rect), maxy = CGRectGetMaxY(rect) ;
CGContextDrawLinearGradient(c, gradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
return;
}
}
- (void)dealloc
{
CGGradientRelease(gradient);
[super dealloc];
}
- (void) setPosition:(CustomCellBackgroundViewPosition)inPosition
{
if(position != inPosition)
{
position = inPosition;
[self setNeedsDisplay];
}
}
@end
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
float ovalWidth,float ovalHeight)
{
float fw, fh;
if (ovalWidth == 0 || ovalHeight == 0) {// 1
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);// 2
CGContextTranslateCTM (context, CGRectGetMinX(rect),// 3
CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);// 4
fw = CGRectGetWidth (rect) / ovalWidth;// 5
fh = CGRectGetHeight (rect) / ovalHeight;// 6
CGContextMoveToPoint(context, fw, fh/2); // 7
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);// 8
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);// 9
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);// 10
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // 11
CGContextClosePath(context);// 12
CGContextRestoreGState(context);// 13
}
tableView.separatorColor
更改表视图边框颜色:
In.h:
#import <QuartzCore/QuartzCore.h>
tableView.layer.masksToBounds=YES;
tableView.layer.borderWidth = 1.0f;
tableView.layer.borderColor = [UIColor whiteColor].CGColor;
这个任务可以很容易地使用PrettyKit完成,只需添加大约5行代码即可。如果您使用nib
文件或storyboard
,也不要忘记应用this little hack。当您使用此方法时,应从PrettyTableViewCell
子类化您的单元格:
#import <PrettyKit/PrettyKit.h>
@class RRSearchHistoryItem;
@interface RRSearchHistoryCell : PrettyTableViewCell
cellForRowAtIndexPath
的示例:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"RRSearchHistoryCell";
RRSearchHistoryCell *cell = (RRSearchHistoryCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if ( cell == nil ) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"RRSearchHistoryCell" owner:self options:nil];
cell = topLevelObjects[0];
cell.gradientStartColor = RGB(0xffffff);
cell.gradientEndColor = RGB(0xf3f3f3);
}
RRSearchHistoryItem *item = _historyTableData[indexPath.row];
[cell setHistoryItem:item];
[cell prepareForTableView:tableView indexPath:indexPath];
return cell;
}