How to show a light reasonable cell selected image / color ?

Discussion in 'iOS Programming' started by Jules2010, May 22, 2010.

  1. Jules2010 macrumors member

    Joined:
    Apr 7, 2010
    #1
    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
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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
    
     
  3. Jules2010 thread starter macrumors member

    Joined:
    Apr 7, 2010
    #3
    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 ...
    [​IMG]

    You can see here the green, from your code, at the back.
    [​IMG]

    Can you help me further ?

    TIA
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    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.
     
  5. Jules2010 thread starter macrumors member

    Joined:
    Apr 7, 2010
    #5
    I would like to do that, but I can't find when the row is selected.

    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.
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    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...
     

Share This Page