我正在创建一个包含带有自定义单元格的UITableView的视图 - 我在自定义视图中覆盖drawRect
。我已经尝试重写UITableViewCell并将我的自定义视图添加为IBOutlet,我试图不覆盖它,只是[[cell subviews] objectAtIndex:0];
引用它会产生相同的结果。
当我第一次看到这个视图时,一切都很好。如果我慢慢滚动,一切都很好。一旦我快速滚动,重复使用的单元格显然不会重新绘制,因为我最终得到了自定义绘图,对于特定单元格来说是错误的。
单元格配置方法......
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"DialogCell"];
MaskedRoundedCornerDIalogCell* dialogCell = (MaskedRoundedCornerDIalogCell*)[[[cell contentView] subviews] objectAtIndex:0];
[dialogCell setPadding:10];
if (indexPath.row % 2 == 0) {
[dialogCell setAlignLeft:YES];
[dialogCell setMaskTopLeftOnly];
[[dialogCell textContent] setText:@"LEFT ALIGNED TEXT"];
[[dialogCell textContent] setTextAlignment:NSTextAlignmentLeft];
} else {
[dialogCell setAlignLeft:NO];
[dialogCell setMaskBottomRightOnly];
[[dialogCell textContent] setText:@"RIGHT ALIGNED TEXT"];
[[dialogCell textContent] setTextAlignment:NSTextAlignmentRight];
}
return cell;
}
我的MaskedRoundedCornerDalogCell实现中的自定义绘图代码(扩展UIView并添加到UITableViewCell的类):
- (void) drawRect:(CGRect)rect {
int maxWidth = rect.size.width - 50;
CGRect container;
if (_alignLeft) {
container = CGRectMake(rect.origin.x + _padding, rect.origin.y + _padding, maxWidth - (2* _padding), rect.size.height - (2*_padding));
} else {
container = CGRectMake((rect.size.width - _padding) - (maxWidth - (2* _padding)), rect.origin.y + _padding, maxWidth - (2* _padding), rect.size.height - (2*_padding));
}
UIRectCorner roundedCorners;
if (!_maskTopLeft) {
roundedCorners = roundedCorners | UIRectCornerTopLeft;
}
if (!_maskTopRight) {
roundedCorners = roundedCorners | UIRectCornerTopRight;
}
if (!_maskBottomLeft) {
roundedCorners = roundedCorners | UIRectCornerBottomLeft;
}
if (!_maskBottomRight) {
roundedCorners = roundedCorners | UIRectCornerBottomRight;
}
UIBezierPath* containerBezierPath = [UIBezierPath bezierPathWithRoundedRect:container byRoundingCorners: roundedCorners cornerRadii:CGSizeMake(25.0F, 25.0F)];
[[UIColor lightGrayColor] setFill];
[containerBezierPath fillWithBlendMode: kCGBlendModeNormal alpha:1.0f];
}
任何建议,感激地收到......
答案 0 :(得分:3)
我不确定您是否在drawRect
子类中覆盖UITableViewCell
,或者它是否在自定义UIView
类中。我的建议是在自定义的UIView
课程中进行绘制,然后将该视图添加为您的单元格的子视图 - 以防UITableViewCell
正在drawRect
中执行您的操作意外地压倒一切。
在任何情况下,您看到此行为的原因是因为drawRect
仅在视图首次出现在屏幕上或者无效时才会被调用。来自docs:
首次显示视图或发生使视图的可见部分无效的事件时,将调用此方法。你永远不应该直接调用这个方法。要使视图的一部分无效,从而导致重绘该部分,请调用setNeedsDisplay或setNeedsDisplayInRect:方法。
在单元格的setMask..
方法中,尝试调用[self.customDrawingView setNeedsDisplay]
使图形无效并强制更新。
您可以使用此方法或setNeedsDisplayInRect:来通知系统您的视图内容需要重绘。此方法记录请求并立即返回。在下一个绘图周期之前,视图实际上不会重绘,此时所有无效的视图都会更新。
只有在视图的内容或外观发生变化时,才应使用此方法请求重绘视图。如果只是更改视图的几何图形,则通常不会重绘视图。而是根据视图的contentMode属性中的值调整其现有内容。重新显示现有内容可以避免重绘未更改内容的需要,从而提高性能。
答案 1 :(得分:0)
首先,我不认为,覆盖- (void)drawRect:(CGRect)rect
是解决问题的正确方法。如果你完全知道你在做什么以及你想要实现什么,我的建议是覆盖它 。
根据您提供的图片,您遇到的问题与UITableViewCell
重复使用有关,但不与图纸有关。
问题。当表格视图滚动到达UITableView
的边界以显示新内容时,UITableView
不会创建新的单元格实例。它需要当前不可见的单元格(已滚动出来的单元格在屏幕上显示新单元格)并重新使用它(UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"DialogCell"];
)。在您的示例中,在重用单元格之后执行的代码行仅设置单元格内容文本。从我提供的图像,我看到,文本正确地坐了起来。问题在于细胞背景。由于在重用后没有单行代码来设置单元格背景,因此在重用之前会显示背景。
推荐。显然,每次重复使用时都需要覆盖单元格背景。如果我是你,我会创建一个类UITableViewCell
的子类,让我们说MyTableViewCell
。该单元格的方法如下:
- (void)setupWithSide:(Side)side {
if (side == SideRight) {
[self setupRightAlignedCintent];
[self setupLeftBackground];
}
}
同时,在UITableViewController
你必须
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"DialogCell"];
Side side;
if (indexPath.row % 2 == 0) {
side = SideRight;
} else {
side = SideLeft;
}
[cell setupWithSide:side];
return cell;
}