Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change the height of the placeholder rows in UITableView without creating dummy row?

The row height beyond the last row in TableView (the empty placeholder rows that are just there for visual detail if the number of items is less than the number of rows a TableView can display at once) is always the same as the last row height.

Is it possible to change this without resorting to adding a dummy last row?

Screenshot

like image 848
pixelfreak Avatar asked Nov 13 '22 13:11

pixelfreak


1 Answers

The private UITableView instance method _spacingForExtraSeparators returns the height of the placeholder rows. If you're not writing an app for the App Store, just override that. It returns a CGFloat.

Here's an different approach that is App Store-compliant (as far as I know), and might be easier than creating a dummy row.

UITableView sends itself the layoutSubviews message a lot. It does this whenever it adds, removes, or rearranges cells, and whenever it scrolls (and probably other times too). So let's override layoutSubviews to draw a view that starts at the bottom edge of your table view's last section. The view will be filled with a repeating pattern that looks like placeholder cells, with a height you define.

Create a subclass of UITableView. Give your subclass a UIView *_bottomView instance variable. We need to override layoutSubviews, so we'll initialize _bottomView lazily in that method.

@implementation MyTableView
{
    UIView *_bottomView;
}

Override layoutSubviews. The first thing you do in your layoutSubviews is call [super layoutSubviews] so you'll continue to act like a proper UITableView.

- (void)layoutSubviews
{
    [super layoutSubviews];

The next thing you do is lazily initialize _bottomView.

    if (!_bottomView) {

You need a pattern to fill _bottomView, and it needs to look like placeholder cells. Make an image context that's 1 pixel wide, and as tall as you want a placeholder cell to be. Fill the context with white, and paint a separator line (pixel, really) at the bottom. Get the image from the context.

        UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, placeholderHeight), YES, 0);
        [[UIColor whiteColor] setFill];
        UIRectFill(CGRectMake(0, 0, 1, placeholderHeight));
        [self.separatorColor setFill];
        UIRectFill(CGRectMake(0, placeholderHeight - 1, 1, 1));
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

Next, create _bottomView, set its background "color" to that image as a repeating pattern, and add it to yourself as a subview.

        _bottomView = [[UIView alloc] initWithFrame:CGRectZero];
        _bottomView.opaque = YES;
        _bottomView.backgroundColor = [UIColor colorWithPatternImage:image];
        [self addSubview:_bottomView];
    } // end of if-block

Finally, find the rect of your last section. Use that rect to compute a frame for _bottomView that starts at the bottom of the last section, is plenty tall (twice your own height is more than enough), and is as wide as the last section's rect.

    int lastSectionIndex = [self.dataSource numberOfSectionsInTableView:self] - 1;
    if (lastSectionIndex < 0)
        lastSectionIndex = 0;
    CGRect lastSectionRect = [self rectForSection:lastSectionIndex];
    CGRect bottomViewFrame = CGRectMake(lastSectionRect.origin.x, CGRectGetMaxY(lastSectionRect), lastSectionRect.size.width, self.bounds.size.height * 2);
    _bottomView.frame = bottomViewFrame;

Finally, make sure _bottomView is your frontmost subview so it will overdraw UITableView's placeholder cells.

    [self bringSubviewToFront:_bottomView];
} // end of layoutSubviews

The end.

@end
like image 53
rob mayoff Avatar answered Nov 16 '22 03:11

rob mayoff