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

时间:2013-02-03 05:02:16

标签: iphone ios uitableview

我正在尝试在我的表格视图中绘制装饰UITableViewCell,文本横幅看起来像一个邮票,对角线横跨单元格的左上角。

我可能完全在错误的地方做这件事,但我要覆盖-layoutSubviews来添加图层。我尝试在-drawRect:中进行此操作,但是当表格呈现时,横幅最终被表格视图的imageView覆盖(即图层位于图像视图下方,因为稍后会添加图像视图)。

我真的很难为此得到正确的数学。我已经计算过,假设横幅从距离单元顶部40个点开始,距左边40个点,正好在-45º角度,斜边将是56个点。所以我将CALayer宽56点,然后旋转-45º,这是有效的。问题是细胞内的位置......它坐在细胞内,而不是靠在它的边缘。

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

感觉就像我在这里需要的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];
    }
}

Banner sits in the wrong place

1 个答案:

答案 0 :(得分:7)

图层应该去哪里?

让我们画一幅图:

enter image description here

我们可以更进一步做一些触发,但让我们停在这里。很明显,横幅的中间顶点应该是(20,20)。我们可以告诉Core Animation这样做。

定位图层

从四个不同的步骤来考虑它:

  1. 设置图层的大小
  2. 确定图层中的哪个点是方便的参考点
  3. 设置参考点的位置
  4. 围绕参考点旋转图层
  5. 这些属性对应于四个属性:boundsanchorPointpositiontransform

    您不想触及frame属性,因为其值派生自 boundspositiontransform,和anchorPoint。如果您尝试设置frame,则CALayer会尝试反转transform,将其应用于您提供的矩形,然后设置boundsposition。这可能无法给出你想要的结果,所以你最好完全忽略它 - 不要那么混乱。

    (有关详细信息,请参阅Core Animation Guide,特别是Layer Objects Define Their Own Geometry部分。)

    在代码中,我们将:

    1. bounds设置为矩形0, 0, width, height。 (我故意将width留给你 - 它必须超过56个。)
    2. anchorPoint设置为0.5, 0点。换句话说,沿着图层宽度的一半,以及图层的顶部。
    3. position设置为20, 20点。
    4. transform设置为旋转45°。
    5. 顺便说一下,在下面的代码中,我设置了affineTransform而不是transform,只是因为它对于简单的二维转换来说稍微方便一些。

      何时设置图层

      你是正确的-drawRect:是创建和添加图层的错误位置。该方法应该绘制到视图的内容(其CGContext)但是 nothing else。

      layoutSubviews可以使用,但它会比您预期的更频繁地被调用,并且您不希望每次都创建和添加新图层。

      看起来你只需要设置一次图层的几何图形,而不要再触摸它。为什么不在更改hasBanner属性时创建或销毁图层?

      @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;
              }
          }
      }