How to set selected background color on grouped UITableView
I've tried vario开发者_开发问答us approaches with no success. Its grouped UITableView. Want to change the background color of the selected cell.
I've tried creating a view, setting the background color and setting it to cell.selectedBackgroundView. It works to change the color, but the rounded corners of a section are lost.
You can create 4 different images, 1 for top, 1 for bottom, 1 for middle, and 1 for top/bottom (rounded on all 4 corners). Then set the background view to your custom image, depending on the position in the table. Alternatively, if you want to use a view, here's a custom view that rounds only specific corners:
.h
#import <UIKit/UIKit.h>
enum {
RoundedCornerNone = 0,
RoundedCornerUpperRight = 1 << 0,
RoundedCornerLowerRight = 1 << 1,
RoundedCornerLowerLeft = 1 << 2,
RoundedCornerUpperLeft = 1 << 3
};
typedef NSUInteger RoundedCornerOptions;
@interface PartiallyRoundedView : UIView
@property (nonatomic, assign) RoundedCornerOptions roundedCorners;
@end
.m
#import "PartiallyRoundedView.h"
@implementation PartiallyRoundedView
@synthesize roundedCorners;
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)drawRect:(CGRect)rect
{
float radius = 10;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
CGContextBeginPath(context);
CGContextSetRGBStrokeColor(context, .6, .6, .6, 1);
CGContextSetRGBFillColor(context, .968, .968, .968, 1);
CGContextMoveToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y); //Draw top line
if (self.roundedCorners >=8) { //Round upper-left corner
CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius,
-M_PI / 2, M_PI, 1);
self.roundedCorners-=8;
}
else {
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + radius);
}
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius); //Draw left line
if (self.roundedCorners >=4) { //Round lower-left corner
CGContextAddArc(context, rect.origin.x + radius , rect.origin.y + rect.size.height - radius,
radius, M_PI, M_PI / 2, 1);
self.roundedCorners-=4;
}
else {
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height);
CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y + rect.size.height);
}
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height); //Draw bottom line
if (self.roundedCorners >=2) { //Round lower-right corner
CGContextAddArc(context, rect.origin.x + rect.size.width - radius ,
rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
self.roundedCorners-=2;
}
else {
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - radius);
}
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius); //Draw right line
if (self.roundedCorners ==1) { //Round upper-right corner
CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius,
radius, 0.0f, -M_PI / 2, 1);
}
else {
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, rect.origin.y );
}
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
- (void)dealloc {
[super dealloc];
}
@end
You can create an instance of this view (you'll need to add a bit to fill the middle with whatever color you want). Just pass in the correct corner rounding depending on if you are the first, last, middle, or first and last cell.
If you'd like to implement this feature with Core Graphics (without using images), give this a shot. My approach takes the same concept as your selected answer, yet uses a simple if/else
(or switch:case
depending on your data source size) to draw the correct background view for your grouped UITableViewCell. The following code only need to be included in your implementation file:
.m
UIView *bgColorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width-24, 69)];
bgColorView.backgroundColor = [UIColor magentaColor];
UIBezierPath *maskPath;
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bgColorView.bounds;
if (row == 0) {
maskPath = [UIBezierPath bezierPathWithRoundedRect:bgColorView.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(8.0, 8.0)];
maskLayer.frame = CGRectOffset(bgColorView.bounds, 1, 0);
if ([self.tableView numberOfRowsInSection:1] == 1) {
maskPath = [UIBezierPath bezierPathWithRoundedRect:bgColorView.bounds
byRoundingCorners:(UIRectCornerAllCorners)
cornerRadii:CGSizeMake(8.0, 8.0)];
}
} else if (row >= [self.tableView numberOfRowsInSection:1]-1) {
maskPath = [UIBezierPath bezierPathWithRoundedRect:bgColorView.bounds
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(8.0, 8.0)];
maskLayer.frame = CGRectOffset(bgColorView.bounds, 1, 0);
} else {
maskPath = [UIBezierPath bezierPathWithRoundedRect:bgColorView.bounds
byRoundingCorners:nil
cornerRadii:CGSizeMake(0.0, 0.0)];
}
maskLayer.path = maskPath.CGPath;
bgColorView.layer.mask = maskLayer;
cell.selectedBackgroundView = bgColorView;
If you've utilized reuseable cells, the drawing should only occur once for each type.
Hope this helps someone who stumbles onto this thread... Cheers!
If you just want to change the selection color, look at this suggestion: UITableView Cell selected Color? Post this in the CellForRowAtIndexPath-Method:
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:[UIColor redColor]];
bgColorView.layer.cornerRadius = 10;
[cell setSelectedBackgroundView:bgColorView];
[bgColorView release];
and don't forget to import QuartzCore. Works for me (iOS 5)
精彩评论