我正在尝试在我的表格视图中绘制装饰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];
}
}
答案 0 :(得分:7)
让我们画一幅图:
我们可以更进一步做一些触发,但让我们停在这里。很明显,横幅的中间顶点应该是(20,20)
。我们可以告诉Core Animation这样做。
从四个不同的步骤来考虑它:
这些属性对应于四个属性:bounds
,anchorPoint
,position
和transform
。
您不想触及frame
属性,因为其值派生自 bounds
,position
,transform
,和anchorPoint
。如果您尝试设置frame
,则CALayer会尝试反转transform
,将其应用于您提供的矩形,然后设置bounds
和position
。这可能无法给出你想要的结果,所以你最好完全忽略它 - 不要那么混乱。
(有关详细信息,请参阅Core Animation Guide,特别是Layer Objects Define Their Own Geometry部分。)
在代码中,我们将:
bounds
设置为矩形0, 0, width, height
。 (我故意将width
留给你 - 它必须超过56个。)anchorPoint
设置为0.5, 0
点。换句话说,沿着图层宽度的一半,以及图层的顶部。position
设置为20, 20
点。transform
设置为旋转45°。顺便说一下,在下面的代码中,我设置了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;
}
}
}