开发者

UITableViewCell background size

I'm trying to set the size of my开发者_JAVA技巧 background to be a little shorter than the default, creating some space between the cells. This has proven to be difficult. Setting the frame of the background view seems to do nothing:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    NSString *reuseIdentifier = @"cell";
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

    if (!cell)
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];

    // Set up the cell...

    cell.contentView.backgroundColor = [UIColor clearColor];

    cell.backgroundView = [[[UIView alloc] initWithFrame:CGRectMake(0, 4, 320, 42)] autorelease];
    cell.backgroundView.backgroundColor = [UIColor blackColor];
    cell.backgroundView.alpha = .2;

    cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:CGRectMake(0, 4, 320, 42)] autorelease];
    cell.selectedBackgroundView.backgroundColor = [UIColor whiteColor];
    cell.selectedBackgroundView.alpha = .2;

    cell.font = [UIFont fontWithName:@"MarkerFelt-Thin" size:22.0f];
    cell.selectedTextColor = [UIColor blackColor];
    cell.textColor = [UIColor whiteColor];

    NSDictionary *dict = [files objectAtIndex:indexPath.row];

    cell.text = [dict objectForKey:@"name"];

    return cell;
}

Any help?

Also, setting the selected background view doesn't do anything. When a cell is selected, the background is completely blank. Why is this?

I'm using iPhone OS 2.2.1.

I also do this:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.rowHeight = 50.0f;
}

You can download the code here (made a small project for this issue only):

http://dl.dropbox.com/u/608462/tabletest2.zip


The backgroundView is not a normal view, there's something going on behind the scenes. Check this link out:

Difference between background view and content view in uitableviewcell

Specifically, from the documentation:

backgroundView: The default is nil for cells in plain-style tables (UITableViewStylePlain) and non-nil for grouped-style tables UITableViewStyleGrouped). UITableViewCell adds the background view as a subview behind all other views and uses its current frame location.

Hence: it doesn't really have a frame location, it uses the cell's frame location.

This code worked:

UIImageView *bgView = [[UIImageView alloc] init]; // Creating a view for the background...this seems to be required.
bgView.backgroundColor = [UIColor redColor];
cell.backgroundView = bgView;

UIImageView *bgImageView = [[UIImageView alloc] init]; // Creating a subview for the background...
bgImageView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];
[bgImageView setFrame:CGRectInset(cell.bounds, 1, 1)];

[cell.backgroundView addSubview:bgImageView]; // Assigning the subview, and cleanup.
[bgImageView release];
[bgView release];

Spent about an hour trying to figure this out...but it works. This is code in the cellForRowAtIndexPath delegate method--I won't cover the whole thing here obviously.


morgancodes' solution led me into the right direction.

I added a sublayer to the background view and styled it. When setting the background color of the background view to clearColor, the sublayer is the only thing showing.

UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIColor clearColor];

CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor colorWithWhite:1 alpha:0.8].CGColor;
sublayer.frame = CGRectMake(15, 3, tableView.frame.size.width - 45, 38);
sublayer.cornerRadius = 5;
[backgroundView.layer addSublayer:sublayer];

cell.selectedBackgroundView = backgroundView;


Here's a completely different method from what you're trying.

One thing I like to do is use a custom image for the backgroundView and selectedBackgroundView, rather than let the iPhone handle the coloring tasks. This gives me a lot more flexibility on how the cell is rendered. All it takes is adding something like this:

  cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"normal.png"]];
  cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"selected.png"]];

To:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;


Yet another approach: add a sublayer to your background. I added the following to the initialization of a UITableViewCell subclass and it seems to work great.

  UIView* backgroundView = [[UIView alloc] initWithFrame: self.contentView.frame ];

  backgroundView.layer.frame = CGRectInset(backgroundView.layer.frame, 20, 20);

  CALayer *sublayer = [CALayer layer];
  sublayer.backgroundColor = [UIColor colorWithWhite:0.69 alpha:1].CGColor;
  sublayer.frame = CGRectMake(INDENT, 0, width - (INDENT * 2), [ChuckWagonTableViewCellCell cellHeight]) ;
  [backgroundView.layer addSublayer:sublayer];

  self.selectedBackgroundView = backgroundView;


Try this:

UIView *bg = [[UIView alloc] initWithFrame: CGRectInset(cell.frame, 0.0, 2.0)];
bg.backgroundColor = [UIColor whiteColor];
cell.backgroundView = bg;

Also don't forget to set background color and separator color to clear in viewDidLoad():

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.separatorColor = [UIColor clearColor];
    self.tableView.backgroundColor = [UIColor clearColor];
}


When messing with the background view, I would do it in: - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

rather than in: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


Try using:

cell.backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 4.0, 320.0, 40.0)]];

For the second question, did you implement:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;


What i think is happening, is that when you select a row, internally the selectedbackgroundview's alpha value is se to 1, thus showing it completely white.


I had a similar problem, and none of the answers seemed to fit in my case. All my rows have the same height in this case, but with some math this could be adapted to accomodate rows with different heights.

I had set the height in my controller, by using the UITableViewDelegate method. I have an instance variable called cellBackgroundImage on my controller that is the UIImage that will be used for the UITableViewCell background. The UITableView background is set to [UIColor clearColor].

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return cellBackgroundImage.size.height + SPACING_HEIGHT;
}

Where SPACING_HEIGHT is a #define constant for the gap height.

Then, the trick was to use an UIView that would wrap the UIImageView that will be the cell's background. I accomplished this by doing:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell"];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"ContentCell"] autorelease];
        CGFloat height = [self tableView:tableView heightForRowAtIndexPath:indexPath];
        cell.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, height);
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        UIView *backView = [[UIView alloc] initWithFrame:CGRectInset(cell.frame, 0, 0)];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:cellBackgroundImage];
        [backView insertSubview:imageView atIndex:0];
        cell.backgroundView = backView;
        [backView release];
        [imageView release];
    }

    return cell;
}

Then, by setting cell.backgroundView = backView to the UIView with the UIImageView that contains my background, i managed to achieve the gap effect between rows. I hope this helps.


A possible solution could be to subclass UIView and add color and height arguments (if you only want to change the height, otherwise you can pass a size/rect). Note that a background color needs to be set, otherwise you'll see a blank area.

- (id)initWithColor:(UIColor *)color height:(CGFloat)height backgroundColor:(UIColor *)backgroundColor;
{
    self = [super init];

    if (self != nil)
    {
        _color = color;
        _height = height;
        _backgroundColor = backgroundColor;
    }

    return self;
}

Add the appropriate properties:

@interface CellSelectedBackgroundView ()
@property (strong, nonatomic) UIColor *color;
@property (strong, nonatomic) UIColor *backgroundColor;
@property (assign, nonatomic) CGFloat height;
@end

And in drawRect: you can fill the area:

- (void)drawRect:(CGRect)rect
{
    [self.backgroundColor setFill];
    UIRectFill(rect);

    [self.color setFill];
    CGRect frame = CGRectMake(0, 0, self.bounds.size.width, self.height);

    UIRectFill(frame);
}

Simply initialize you custom UIView subclass and set it as the selectedBackgroundView property of your UITableViewCell.


Try adding a subview into your backgroundViews instead of modifying them directly:

UIView *selectedView = [[UIView alloc] initWithFrame:UIEdgeInsetsInsetRect(cell.frame, UIEdgeInsetsMake(8, 8, 8, 8))];
selectedView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = [UIView new];
cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
[cell.selectedBackgroundView addSubview:selectedView];

I had the same problem as yours with the selectedBackgroundView and this worked for me ;)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜