我最近发现了一篇关于使用UITableViewCells提高滚动性能的精彩文章:http://engineering.twitter.com/2012/02/simple-strategies-for-smooth-animation.html - 虽然本文中有很多很棒的提示,但有一个特别令我很感兴趣:
Twitter for iPhone 4.0的推文在微妙的纹理背景上有一个投影。这提出了一个挑战,因为混合是昂贵的。 我们通过通过从单元格的内容区域中分割阴影区域来减少核心动画必须考虑非透明的区域来解决这个问题。
使用iOS模拟器,点击调试 - 颜色混合图层会显示如下内容:
以红色标记的区域混合,绿色区域不透明。大。文章没有提到的是:我该如何实现?我的理解是UIView要么是不透明的,要么不是。在我看来,实现这一目标的唯一方法是使用子视图,但文章明确指出,因为是一个天真的实现:
相反,我们的推文单元格包含一个没有子视图的视图;一个drawRect:绘制所有内容。
那么我如何划分不透明的东西,以及我的单个drawRect:方法中没有的东西?
答案 0 :(得分:3)
在你展示的例子中,我不相信他们在视图中显示背景。我认为他们正在模拟核心图形的背景。换句话说,在每个单元格中,它们为背景绘制浅灰色。然后他们绘制阴影(使用透明度),最后他们在顶部绘制其余的不透明内容。我可能是错的,但我不相信你可以使视图的一部分透明。如果是这样,我会非常非常感兴趣,因为我一直使用核心图形,但我避免使用圆角,因为将整个视图混合起来似乎并不值得。
<强>更新强>
在做了一些研究并查看Apple的文档后,我不相信只有部分视图是不透明的。此外,在通过Twitter的博客文章阅读后,我认为他们并不是说他们这样做了。请注意,当他们说:
相反,我们的推文单元格包含一个没有子视图的视图;一个drawRect:绘制所有内容。
他们专门讨论UILabel
和UIImageView
。换句话说,他们不是使用那些视图,而是使用Core Graphics直接绘制图像。至于UILabels,我个人使用Core Text,因为它有更多的字体支持,但他们也可能使用更简单的东西,如NSString的drawAtPoint:withFont:
方法。但他们试图解决的主要问题是,单元格的内容都是CG绘图。
然后他们转到新的部分:避免混合。在这里,他们指出他们避免混合:
将阴影区域与细胞的内容区域分开。
执行此操作的唯一方法是使用不同的视图。他们可以使用两种方法,但首先请注意单元格分隔符本身是叠加层(由tableView提供)。第一种方法是在单元格内使用多个视图。第二种方法是通过将适当的视图插入UIScrollView来在单元格后面/上面覆盖/覆盖阴影/混合视图。鉴于他们之前关于每个单元只有一个view / drawRect的陈述,这可能就是他们正在做的事情。每种方法都会遇到挑战,但我个人认为将单元格拆分为3个视图(阴影,内容,阴影)会更容易。这将使处理第一个/最后一个单元格情况变得容易得多。
答案 1 :(得分:0)
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);
答案 2 :(得分:0)
我的观点是:不要让Core Animation使用各种layer properties绘制阴影。只需向两边绘制一个预呈现的图像,这实际上是一个阴影。要在stretch draw中计算单元格的可变高度,可以解决问题。
编辑: 如果背景很明显,可以将预呈现的阴影应用于双方,而不会知道它会影响视觉吸引力。
如果不适用,则必须将tableview缩小到没有阴影的大小。然后可以混合阴影,而不是为每个单元格进行混合,而只是“在顶部”。它真的不滚动。这只有在阴影没有任何“纹理”时才会起作用,否则会注意到它只是应用在顶部。