使用CALayer将对angular横幅/徽章添加到UITableViewCell的angular落

我试图绘制装饰UITableViewCell在我的表视图与文字横幅看起来像一个邮票,对angular线在整个单元格的左上angular。

我可能完全在错误的地方做这个,但我重写-layoutSubviews添加图层。 我尝试在-drawRect:做这-drawRect:但是当表格呈现时(即,图层在图像视图下方,随后添加图像视图),横幅最终由表视图的-drawRect:覆盖。

我真的很难得到这个math正确的。 我计算过,假设条幅从单元的顶部开始40点,从左侧开始40点,正好在-45°处,斜边是56点。 所以我做了CALayer 56点宽,然后旋转它-45º,这是有效的。 问题在于细胞内的位置……它坐在牢房里,而不是靠在它的边缘上。

而不是我应用试验和错误,以得到这个在正确的地方,有人可以帮我的math? 显然我需要移动图层旋转它。

感觉像anchorPoint是我需要在这里,但似乎实际上移动层,所以我必须错过(没有双关语的意思)。

 - (void)layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectMake(10, 10, 50, 50); if (self.hasBanner) { CALayer *banner = [CALayer layer]; banner.backgroundColor = [UIColor colorWithRed:.5f green:.5f blue:.5f alpha:1.f].CGColor; banner.frame = CGRectMake(0, 40-15, 56, 15); banner.anchorPoint = CGPointMake(0, 1); // this just makes it worse banner.transform = CATransform3DMakeRotation(-45.0 / 180.0 * M_PI, 0.0, 0.0, 1.0); [self.layer addSublayer:banner]; } } 

横幅坐错了地方

图层应该去哪里?

我们来画一个图表:

在这里输入图像说明

我们可以走得更远,做点什么,但是我们在这里停下来。 很明显,横幅的中间点应该在(20,20) 。 我们可以告诉核心animation做到这一点。

定位图层

从四个单独的步骤来考虑它:

  1. 设置图层的大小
  2. 确定图层中的哪个点是方便的参考点
  3. 设置参考点的位置
  4. 围绕参考点旋转图层

这些对应于四个属性: boundsanchorPointpositiontransform

您不想触摸frame属性,因为它的值是 boundspositiontransformanchorPoint 派生的。 如果您尝试设置frame ,则CALayer将尝试反转transform ,将其应用于您指定的矩形,然后设置boundsposition 。 这可能不会给你想要的结果,所以你最好完全忽略它 – 不要那么混淆。

(有关更多信息,请参阅“ 核心animation指南” ,特别是“ 图层对象定义其自己的几何graphics”一节 。)

在代码中,我们将:

  1. bounds设置为矩形0, 0, width, height 。 (我故意留给你的width – 它将不得不超过56)。
  2. anchorPoint设置为点anchorPoint 。 换句话说,在层的宽度的一半,在层的顶部。
  3. position设置到点20, 20
  4. 设置transform旋转45°。

顺便说一下,在下面的代码中,我设置了affineTransform而不是transform ,只是因为它对于简单的2-D变换稍微方便一些。

何时设置图层

你是正确的, -drawRect:是创build和添加图层的错误地方。 该方法应该绘制到视图(它的CGContext )的内容,但别无其他。

layoutSubviews可以正常工作,但会比你期望的更频繁地被调用,而且你不想每次创build和添加一个新的图层。

看起来你只需要设置一次图层的几何graphics,而不再触摸它。 为什么不只是当你的hasBanner属性被改变时创build或销毁图层?

 @interface MyTableViewCell () @property (nonatomic) BOOL hasLayer; @property (nonatomic) CALayer* bannerLayer; @end - (void)setHasBanner:(BOOL)hasBanner { if (hasBanner != _hasBanner) { _hasBanner = hasBanner; if (hasBanner) { CALayer* banner = [CALayer layer]; banner.backgroundColor = [UIColor colorWithRed:.5f green:.5f blue:.5f alpha:1.f].CGColor; banner.bounds = CGRectMake(0, 0, 56, 15); banner.anchorPoint = CGPointMake(0.5, 0); banner.position = CGPointMake(20, 20); banner.affineTransform = CGAffineTransformMakeRotation(-45.0 / 180.0 * M_PI); // Add the layer to the view, and remember it for later [self.layer addSublayer:banner]; self.bannerLayer = banner; } else { // Remove the layer from the view, and discard it [self.bannerLayer removeFromSuperlayer]; self.bannerLayer = nil; } } }