CAGradientLayer不会从视图中删除self

时间:2016-03-02 18:04:37

标签: ios objective-c cagradientlayer

我创建了CAGradientLayer并将其添加到UIView

CAGradientLayer *layer = [UIColor lightBlueSpreadGradient];
layer.frame = self.contentView.bounds;
layer.cornerRadius = self.contentView.layer.cornerRadius;
self.gradientLayer = layer;

[self.contentView.layer insertSublayer:layer atIndex:0];

我保留了对它的引用,以便我可以在以后删除它:

[self.gradientLayer removeFromSuperlayer];

但它实际上并没有消除。我知道它被调用了,取消选择方法中的其他所有内容都按预期工作:

-(void)setIsActive:(BOOL)isActive {
    _isActive = isActive;

    if (_isActive) {
        CAGradientLayer *layer = [UIColor lightBlueSpreadGradient];
        layer.frame = self.contentView.bounds;
        layer.cornerRadius = self.contentView.layer.cornerRadius;
        self.gradientLayer = layer;
        DLog(@"inserting self.gradientLayer: %@", self.gradientLayer);

        [self.contentView.layer insertSublayer:layer atIndex:0];
    }
    else {
        DLog(@"is active is false");
        DLog(@"removing overlay");

        DLog(@"self.gradientLayer: %@", self.gradientLayer);
        [self.gradientLayer removeFromSuperlayer];

    }
}

日志:

DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | inserting self.gradientLayer: <CAGradientLayer: 0x7e26cce0>
DEBUG | -[DatasetTrayCell setIsActive:] | is active is false
DEBUG | -[DatasetTrayCell setIsActive:] | removing overlay
DEBUG | -[DatasetTrayCell setIsActive:] | removing self.gradientLayer: <CAGradientLayer: 0x7e26cce0>

点击手势:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapDectected)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;

[self addGestureRecognizer:singleTap];

单击检测方法:

-(void)singleTapDectected {
    DLog(@"tap detected");

    if (self.isActive) {
        self.isActive = NO;
    }
    else {
        self.isActive = YES;
    }

}

日志:

DEBUG | -[DatasetTrayCell singleTapDectected] | tap detected

知道它为什么不删除?

编辑:

好的,我发现了这个问题,但我不明白为什么会出现问题。所以我设置isActive的完整方法:

-(void)setIsActive:(BOOL)isActive {
    DLog(@"setting isActive");

    _isActive = isActive;

    if (_isActive) {
        if ([self.delegate respondsToSelector:@selector(datasetTrayCell:displayWithCompletionBlock:)]) {
            [self.delegate datasetTrayCell:self displayWithCompletionBlock:^{
                CAGradientLayer *layer = [UIColor lightBlueSpreadGradient];
                layer.frame = self.contentView.bounds;
                layer.cornerRadius = self.contentView.layer.cornerRadius;
                self.gradientLayer = layer;
                DLog(@"inserting self.gradientLayer: %@", self.gradientLayer);

                [self.contentView.layer insertSublayer:layer atIndex:0];
                DLog(@"self.gradientLayer.superlayer: %@", self.gradientLayer.superlayer);
                DLog(@"self.contentView.layer.sublayers: %@", self.contentView.layer.sublayers);

            }];
        }
    }
    else {
        if ([self.delegate respondsToSelector:@selector(datasetTrayCell:removeWithCompletionBlock:)]) {
            [self.delegate datasetTrayCell:self removeWithCompletionBlock:^{
                DLog(@"self.contentView.layer.sublayers: %@", self.contentView.layer.sublayers);
                [self.gradientLayer removeFromSuperlayer];
                DLog(@"self.gradientLayer.superlayer: %@", self.gradientLayer.superlayer);
                DLog(@"removing self.gradientLayer: %@", self.gradientLayer);
            }];
        }
        else {
            DLog(@"delegate does not respond to removeOverlayWithCompletionBlock");
        }
    }
}

在块中创建CAGradientLayer的事实导致它被创建两次:

DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | inserting self.gradientLayer: <CAGradientLayer: 0x787bdc80>
DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | self.gradientLayer.superlayer: <CALayer: 0x7db473f0>
DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | self.contentView.layer.sublayers: (
    "<CAGradientLayer: 0x787bdc80>",
    "<CALayer: 0x787bd750>"
)

再次:

DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | inserting self.gradientLayer: <CAGradientLayer: 0x78631ce0>
DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | self.gradientLayer.superlayer: <CALayer: 0x7db473f0>
DEBUG | __31-[DatasetTrayCell setIsActive:]_block_invoke | self.contentView.layer.sublayers: (
    "<CAGradientLayer: 0x78631ce0>",
    "<CAGradientLayer: 0x787bdc80>",
    "<CALayer: 0x787bd750>"
)

一旦我从块中移除了那些代码,它就会按预期执行(它只创建1个渐变):

-(void)setIsActive:(BOOL)isActive {
    DLog(@"setting isActive");

    _isActive = isActive;

    if (_isActive) {
        CAGradientLayer *layer = [UIColor lightBlueSpreadGradient];
        layer.frame = self.contentView.bounds;
        layer.cornerRadius = self.contentView.layer.cornerRadius;
        self.gradientLayer = layer;

        [self.contentView.layer insertSublayer:layer atIndex:0];

        if ([self.delegate respondsToSelector:@selector(datasetTrayCell:displayWithCompletionBlock:)]) {
            [self.delegate datasetTrayCell:self displayWithCompletionBlock:^{
            }];
        }
    }
    else {
        [self.gradientLayer removeFromSuperlayer];

        if ([self.delegate respondsToSelector:@selector(datasetTrayCell:removeWithCompletionBlock:)]) {
            [self.delegate datasetTrayCell:self removeWithCompletionBlock:^{
            }];
        }
    }
}

为什么会发生这种情况,我还不确定。

2 个答案:

答案 0 :(得分:2)

  

因此渐变失去了对插入位置的引用。但我不知道如何或为什么。

它没有失去参考&#34;。您似乎对self.gradientLayer有强烈的引用。并且您已从其超级层中删除了self.gradientLayer。但是你保留在强有力的参考中。现在你要求它的超级层,自然而然,它没有;你删除了它。您在界面中看到的渐变层因此与您正在交谈的渐变层相同。这个故事中有(至少)两个渐变层。事情变得不同步了,这让你感到困惑。但是我向你保证,这层不是行为不端。

答案 1 :(得分:0)

尝试改为:

for (CALayer *layer in self.contentView.layer.sublayers) {
    if([layer isKindOfClass:[GradientLayer class]])
    {
        [layer removeFromSuperlayer];

    }
}