I use the following code to make “fixed” row headers in my UIScrollView descendant. It works well with the Simulator, but unfortunately, it flickers on the iPad. (To the left of the row header views, a white 1px line appears and disappears.) What can be improved?
- (void)initSubviews
{
const int ROW_COUNT = 20;
rowHeaderViews = [[NSMutableArray alloc]initWithCapacity:ROW_COUNT];
rowViews = [[NSMutableArray alloc]initWithCapacity:ROW_COUNT];
[self setContentSize:CGSizeMake(2000, [self frame].size.height)];
for (int i = 0; i < ROW_COUNT; i++)
{
UIView *header = [self createRowHeaderViewForRowNum:i];
[rowHeaderViews addObject:header];
UIView *row = [self createRowViewForRowNum:i];
[rowViews addObject:row];
[self addSubview:row];
[self addSubview:header];
}
[self layoutSubviews];
}
- (void)layoutSubviews
{
int x = [self contentOffset].x;
for (UIView *view in rowHeaderViews) {
[view setFrame:CGRectMake(x, view.frame.origin.y, view.frame.size.width, view.frame.size.height)];
}
}
- (UIView *)createRowHeaderViewForRowNum: (int)rowNum
{
UILabel *view = [[UILabel alloc]initWithFrame:CGRectMake(0, rowNum * 20, 200, 20)];
[view setBackgroundColor:[UIColor colorWithWhite:0.8*(20-rowNum)/20 alpha:1]];
[view setText:[NSString stringWithFormat:@"Row Header %d", rowNum]];
return view;
}
- (UIView *)createRowViewForRowNum: (int)rowNum
{
UILabel *view = [[UILabel alloc]initWithFrame:CGRectMake(200, rowNum * 20, 1800, 20)];
[view setBackgroundColor:[UIColor colorWithRed:rowNum/20.0 green:0 blue:0 alpha:1]];
[view setText:[NSString stringWithFormat:@"Row Content %d", rowNum]];
return view;
}
Thank you very much for any help!
EDIT: The iPad has got a Retina display. When using the Simulator with a “normal” iPad, it does not flicker. When switching the Simulator to a “Retina display” iPad, there is this flickering, too. Maybe this is something about the points/pixels difference?
I found the bug on my own. Sorry for bothering you.
In case anybody else has got the same problem:
contentOffset.x is a float value and contains .5 values for Retina displays.
Assigning it to an int variable in
layoutSubviewscaused the problem.This is the fix (note I replaced ‘int’ with ‘CGFloat’):