13

我最近看到了这篇关于使用 UITableViewCells 提高滚动性能的精彩文章:http: //engineering.twitter.com/2012/02/simple-strategies-for-smooth-animation.html -- 虽然可以在其中找到许多很棒的技巧文章中,有一篇特别让我感兴趣:

iPhone 4.0 版 Twitter 中的推文在微妙的纹理背景之上有一个投影。这提出了一个挑战,因为混合成本很高。我们通过减少核心动画必须考虑的非透明区域来解决这个问题,方法是将阴影区域与单元格的内容区域分开。

使用 iOS 模拟器,单击Debug - Color Blended Layers将显示如下内容:

TwitterTableViewCell

用红色标记的区域是混合的,绿色区域是不透明的。伟大的。这篇文章没有提到的是:我该如何实现这个?我的理解是 UIView 要么不透明,要么不透明。在我看来,实现这一点的唯一方法是使用子视图,但文章明确指出这是一个幼稚的实现

相反,我们的 Tweet 单元格包含一个没有子视图的视图;一个drawRect:绘制一切。

那么我如何区分不透明的部分,以及我的单个 drawRect: 方法中不包含的部分?

4

3 回答 3

3

在您展示的示例中,我不相信他们通过视图显示背景。我认为他们正在模拟核心图形中的背景。换句话说,在每个单元格中,他们为背景绘制了浅灰色。然后他们绘制阴影(使用透明度),最后在顶部绘制其余的不透明内容。我可能是错的,但我不相信您可以使部分视图透明。如果是这样,我会对它非常非常感兴趣,因为我一直使用核心图形,但我避免使用圆角,因为为它混合整个视图似乎并不值得。

更新

在进行了更多研究并查看了 Apple 的文档之后,我不相信只有部分视图是不透明的。此外,在阅读了 Twitter 的博客文章后,我认为他们并不是在说他们这样做了。请注意,当他们说:

相反,我们的 Tweet 单元格包含一个没有子视图的视图;一个drawRect:绘制一切。

他们专门谈论UILabelUIImageView。换句话说,他们不是使用那些视图,而是直接使用 Core Graphics 绘制图像。至于 UILabel,我个人使用 Core Text,因为它有更多的字体支持,但他们也可能使用更简单的东西,比如 NSString 的drawAtPoint:withFont:方法。但他们试图传达的主要观点是,单元格的内容都是一张 CG 绘图。

然后他们转移到一个新的部分:避免混合。在这里,他们强调要避免通过以下方式混合:

将阴影区域与单元格的内容区域分开。

做到这一点的唯一方法是使用不同的视图。他们可以使用两种方法,但首先请注意,单元格分隔符本身就是叠加层(由 tableView 提供)。第一种方法是在单元格内使用多个视图。第二种方法是通过将适当的视图插入 UIScrollView 来覆盖/覆盖单元格后面/上方的阴影/混合视图。鉴于他们之前关于每个单元格只有一个 view/drawRect 的声明,这可能就是他们正在做的事情。每种方法都会有其挑战,但我个人认为将单元格拆分为 3 个视图(阴影、内容、阴影)会更容易。这将使处理第一个/最后一个单元格情况变得更加容易。

于 2012-05-14T15:38:36.700 回答
0

我不得不沿着这些思路猜测一些东西
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadows/dq_shadows.html

  CGContextRef context = UIGraphicsGetCurrentContext();

UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:10.0f];

CGContextSaveGState(context);
CGRect leftRect = CGRectZero;
CGContextClipToRect(context, leftRect );
CGContextSetBlendMode(context, kCGBlendModeNormal);
// draw shadow

//    Call the function CGContextSetShadow, passing the appropriate values.
//    Perform all the drawing to which you want to apply shadows.
CGContextSetShadowWithColor(context, CGSizeMake(1.0f, 1.0f), 10.0f, [UIColor blackColor].CGColor);
CGContextAddPath(context, path.CGPath);
CGContextDrawPath(context, kCGPathStroke);


CGContextRestoreGState(context);

CGContextSaveGState(context);
CGRect middleSection = CGRectZero;
CGContextClipToRect(context, middleSection);
CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
CGContextFillRect(context, self.bounds);
// draw opaque
CGContextSetBlendMode(context, kCGBlendModeCopy); 

CGContextRestoreGState(context);
于 2012-05-14T15:38:55.887 回答
0

我的意见是:不要让 Core Animation 使用各种图层属性来绘制阴影。只需在两侧绘制一个预渲染的图像,这实际上是一个阴影。在拉伸绘制中考虑单元格的可变高度可能会奏效。

编辑:如果背景是普通的,可以将预渲染的阴影应用到两侧而不知道它会影响视觉吸引力。

在不适用的情况下,tableview 必须缩小到没有阴影的大小。然后可以混合阴影而不需要对每个单元格进行混合,而只是“在顶部”。它真的不滚动。这仅在阴影没有任何“纹理”时才有效,否则人们会注意到它只是应用在顶部。

于 2012-05-14T18:52:43.190 回答