views:

2089

answers:

4

Hi,

I want to draw the background of a UITableViewCell which has a grouped style. The problem with me is I am not able to call the -(void)drawRect:(CGRect)rect or I think it should be called programmatically...

I have taken code from following link .

http://stackoverflow.com/questions/400965/how-to-customize-the-background-border-colors-of-a-grouped-table-view/1031593#1031593

//
//  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]);
CGContextSetLineWidth(c, 2.0);

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

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


}


- (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
}

but the problem is my drawRect is not getting called automatically.........

I am doing it like this.

CustomCellBackgroundView *custView = [[CustomCellBackgroundView alloc]     initWithFrame:CGRectMake(0,0,320,44)];
[cell setBackgroundView:custView];
[custView release];

and doing this gives me transparent cell. I tried and fought with code but could get any results. Please help me out. I am really having no idea how this code will run.

+2  A: 

If you are targeting iPhone OS 3.0+, all you need to do is this:

cell.backgroundColor = [UIColor redColor];

Substituting whatever UIColor you actually want, of course. The background color will be clipped automatically to the rounded rectangle bounds of the grouped table view cell.

Sbrocket
I am not targeting 3.0+ thats y I had to go with that code
Madhup
+1  A: 

HI GUYS,

I have got this code working....

just did this.....

In CustomCellBackGroundView

- (BOOL) isOpaque {
    return NO;
}



- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self setFillColor:[UIColor colorWithRed:0.07 green:.23 blue:.48 alpha:0.5]];
     [self setBorderColor:[UIColor colorWithRed:0.8 green:0.8 blue:1.0 alpha:0.5]];
     [self setClearsContextBeforeDrawing:YES];
    }
    return self;
}

- (void)setNeedsDisplay{
    [self setNeedsDisplayInRect:self.frame];
}

and in ur UITableViewController class just do this.....

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *MyIdentifier = @"My Identifier";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if(cell==nil){

     cell = [self reuseTableViewCellWithIdentifier:MyIdentifier indexPath:indexPath];

     [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];

     [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
    }

    CustomCellBackgroundView *custview = [[CustomCellBackgroundView alloc] initWithFrame:CGRectMake(0, 0, 320, 35)];

    if(([tbleView numberOfRowsInSection:indexPath.section]-1) == 0){
     custview.position = CustomCellBackgroundViewPositionTop;
    }
    else if(indexPath.row == 0){
     custview.position = CustomCellBackgroundViewPositionTop;
    }
    else if (indexPath.row == ([tbleView numberOfRowsInSection:indexPath.section]-1)){
     custview.position  = CustomCellBackgroundViewPositionBottom;
    }
    else{
     custview.position = CustomCellBackgroundViewPositionMiddle;
    }
    [cell setBackgroundView:custview];
    [custview release];


    UILabel *lbl = (UILabel *)[cell.contentView viewWithTag:101];



     [lbl setText:@"Hurray and thanks to all folks"];

    //[cell setNeedsDisplay];
    return cell;
}

remeber dont do this in (cell==nil) block and give special thanks to all folks at

http://stackoverflow.com/questions/400965/how-to-customize-the-background-border-colors-of-a-grouped-table-view/1031593#1031593

Madhup
A: 

I have to agree with Sbrocket.

You need two lines of code. Four lines if you want to use a custom color for the line separator and border.

// For cell background
 cell.backgroundColor=[UIColor lightGrayColor];

// For tableView line separator (assuming IBOutlet UITableView* table;)
self.table.separatorColor=[UIColor redColor];

//If you need a custom color (I assume you do), then...
 cell.backgroundColor=[UIColor colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha];

Drop in the RGB value for any color you like for both the cell background and line separator.

Couldn't be easier.

Jordan
please try to do this in 2.x and keep the tableStyle grouped then see yours is easier or not ... ;)
Madhup
Why in the world would you want to develop and maintain 2.x code??
Jordan
You're picking up all the development headache, instead of shifting the upgrade burden to your users. This is costing you money as a developer. Very bad. Part of the problem with client/server development. Chrome OS RuleS! ;)
Jordan
A: 

Great code! I'm trying to modify this code to paint a gradient instead a solid color but I'm not succeeding.

Has anyone done this?

Thanks

cbscd