Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Jules2010

macrumors member
Original poster
Apr 7, 2010
34
0
I'm using a table with one row and a UITableViewCellAccessoryDisclosureIndicator to allow selection of a value. I'm using a disabled button to show a stretched image in the cell.

However, for the selectedBackgroundView I can't seem to show anything other than a dark blue color or image, even with the UITableViewCellSelectionStyleGray.

I can't understand why this seems so complicated.

Can anyone offer me any advice ?

TIA
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
If you want to customise the selected background colour it is possible, just rather more involved than you might like (see the SELOC Tech Wiki app in my signature for example: it uses UITableViews a lot with customised colours: my selected highlights are green).

First of all setup the Cell correctly:

Code:
// Called to get a cell for a table view.  If required we actually create a cell and setup all the required customisation
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{	
	static NSString *MyIdentifier = @"MyIdentifier";
	
	// Try to retrieve from the table view a now-unused cell with the given identifier
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
	
	// If no cell is available, create a new one using the given identifier
	if (cell == nil)
	{
		// 3.0 changed: initWithFrame:reuseIdentifier: is depricated so replace it with the suggested new method
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
		// We want to have green text with green highlights to match our overall branding/theme
		cell.textLabel.textColor = SELOC_GREEN;
		cell.selectedBackgroundView = [[[ColourableTableCellBackgroundView alloc] init] autorelease];
		cell.selectedBackgroundView.clearsContextBeforeDrawing = NO;
		cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
		((ColourableTableCellBackgroundView *) cell.selectedBackgroundView).cellBackgroundColor = SELOC_GREEN;
	}
	[cell.backgroundView setNeedsDisplay];
	
	return cell;
}

Note that SELOC_GREEN is a #define for a UIColor.

You then need this custom view:

.h
Code:
//
//  ColourableTableCellBackgroundView.h
//  SELOCTechWiki
//
//  Created by Robbie Duncan on 14/03/2010.
//  Copyright 2010 Robbie Duncan. Rights to copy, modify and distribute this source code and the compiled application granted to SELOC.  All other rights reserved.
//
//  Custom view to draw the background of a table cell.  We can control the colours.
//
#import <Foundation/Foundation.h>
//
// We need to know what sort of shape our cell is : if we are in grouped mode we need rounded corners.  In this case set correctly.  If the table is in non-grouped mode set to middle
typedef enum
{
    CustomCellBackgroundViewPositionTop, // Top cell in a group
    CustomCellBackgroundViewPositionMiddle, // Middle cell in a group or non-grouped table
    CustomCellBackgroundViewPositionBottom, // Bottom cell in a group
    CustomCellBackgroundViewPositionSingle // Single cell in a group (so top and bottom)
} CustomCellBackgroundViewPosition;
//
@interface ColourableTableCellBackgroundView : UIView
{
	UIColor *cellBackgroundColor; // The background colour for the table cell.  Note that the backgroundColor property is not used for this: if we draw rounded corners this is the "show through" color
    CustomCellBackgroundViewPosition position; // One of the above values for position
}
//
// Make ivars properties
@property (nonatomic, retain) UIColor *cellBackgroundColor;
@property (assign) CustomCellBackgroundViewPosition position;
//
@end

.m
Code:
//
//  ColourableTableCellBackgroundView.m
//  SELOCTechWiki
//
//  Created by Robbie Duncan on 14/03/2010.
//  Copyright 2010 Robbie Duncan. Rights to copy, modify and distribute this source code and the compiled application granted to SELOC.  All other rights reserved.
//
//  Custom view to draw the background of a table cell.  We can control the colours.
//
#import "ColourableTableCellBackgroundView.h"
#import "CommonDefines.h"
//
// "Magic number" for how much to round the corners. 8 seems to match the drawing of UITableView
#define ROUND_SIZE 8
//
@implementation ColourableTableCellBackgroundView
//
// Sythesize the properties
@synthesize cellBackgroundColor;
@synthesize position;
//
#pragma mark UIView Methods
//
// Draw the view
// This is largely from http://stackoverflow.com/questions/400965/how-to-customize-the-background-border-colors-of-a-grouped-table-view
-(void)drawRect:(CGRect)rect 
{
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(c, [self.cellBackgroundColor CGColor]);
    CGContextSetStrokeColorWithColor(c, [self.cellBackgroundColor 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;
    }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;         
	}
}
//
@end
 

Jules2010

macrumors member
Original poster
Apr 7, 2010
34
0
Hi,

Thanks for that I have managed to get your code to work. However, it doesn't seem to solve my specific problem. I'm unsure why anything you'd draw on your contentview should remain when you show your selected background view. Heres what I'm doing.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    UILabel *rightLabel = [[UILabel alloc] initWithFrame:CGRectMake(10,0,260,40)];
	if (strTableSelected == @"") {
		rightLabel.text = @"Choose Part";
    } else {
		rightLabel.text = [NSString  stringWithFormat:@"The %@ Part", strTableSelected];
	}		
    //rightLabel.textColor = [UIColor blueColor];
    rightLabel.textAlignment = UITextAlignmentLeft;
    rightLabel.font = [UIFont boldSystemFontOfSize:14];
	rightLabel.backgroundColor = [UIColor clearColor];
    [cell.contentView addSubview:rightLabel];
    [rightLabel release];
	
	cell.selectionStyle = UITableViewCellSelectionStyleGray;
		
	UIButton *btnBackground= [[UIButton alloc] initWithFrame:CGRectMake(0,0,300,45)];
	btnBackground.enabled = NO;
	[AppBasic setButton:btnBackground str:@"blue"];
	[cell.contentView addSubview:btnBackground];
	[btnBackground release];
	
	cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
    return cell;
Code:
+(void)setButton:(UIButton *)button str:(NSString *)str {

	UIImage *buttonImageNormal = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@", @"action-normal-", str, @".png"]];
	
    UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [button setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
	
	UIColor *colorYellow = [UIColor colorWithRed:1.0 green:1.0 blue:0.0 alpha:1.0];
	[button setTitleColor:colorYellow forState:UIControlStateNormal];
	[button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];

	UIImage *buttonImagePressed = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@", @"action-pressed-", str, @".png"]];
    UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
	[button setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];

	UIColor *colorDarkYellow = RGB(210,212,0);
	[button setTitleColor:colorDarkYellow forState:UIControlStateHighlighted];
	[button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateHighlighted];
}

I get a really nice button look on the content view ...
20100523-p2gwyeh8qhcjfbiw1dq5hbs33y.jpg


You can see here the green, from your code, at the back.
20100523-g83ug3be3w8wh6qxutcy7t6txc.jpg


Can you help me further ?

TIA
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Ah, you are doing something very different to me: my content views are transparent so when the row becomes selected I want the background view of the cell to display that. You are basically going to have to deal with this in a different way.

You can either:

1) Draw whatever you want in your content view at the correct time

2) Make your content views transparent and do it my way with a background view for the cell.
 

Jules2010

macrumors member
Original poster
Apr 7, 2010
34
0
1) Draw whatever you want in your content view at the correct time

I would like to do that, but I can't find when the row is selected.

2) Make your content views transparent and do it my way with a background view for the cell.
I did try this, but I update the text once the value is changed and this gets overwritten, so I get two lots of text drawn.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
I did try this, but I update the text once the value is changed and this gets overwritten, so I get two lots of text drawn.

Sorry, I don't think I understand what you are saying. You set the text value of a view. Then you change this value and you are getting the old value and the new value shown? If this is the case then something is wrong somewhere...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.