删除索引 0 处的 CALayer

发布于 2024-10-03 11:42:56 字数 205 浏览 0 评论 0原文

我添加了一个渐变层:

[theView.layer insertSublayer:gradient atIndex:0];

稍后在另一种方法中我想删除该层。我想我应该获取子层数组,然后获取索引 0 处的子层并对其调用removeFromSuperlayer。这是正确的方法吗?如果不正确,你可以这样做吗?

干杯。

I've added a gradient layer:

[theView.layer insertSublayer:gradient atIndex:0];

And later on in another method I want to remove this layer. I figured I should get the array of sublayers then get the sublayer at index 0 and call removeFromSuperlayer on it. Is this the correct way or if not can you do it?

Cheers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

嘿咻 2024-10-10 11:42:56

您可以按照您描述的方式进行操作,但不太可靠。问题是,如果您在添加和删除之间对子图层执行任何操作,子图层的索引可能会更改,并且最终会删除您不想要的内容。

最好的办法是保留对该图层的引用,稍后当您想要删除它时,只需调用 [theLayer removeFromSuperlayer]

希望它有帮助

You can do it the way you described but it isn't so reliable. The problem is that if you do anything with the sublayers in between the addition and removal, the index of the sublayer can change and you end up removing something you didn't want to.

The best thing is to keep a reference to that layer and later when you want to remove it just call [theLayer removeFromSuperlayer]

Hope it helps

回心转意 2024-10-10 11:42:56

Funfunfun...

您可以使用两个图层属性(无论哪种情况,您都必须迭代图层):

  • CALayer.name“某些布局管理器使用它来标识图层”。将其设置为合理保证唯一的值(例如“MyClassName.gradient”)。
  • CALayer.style 是一个字典。您可以使用 CoreAnimation 未使用的键(例如 NSMutableDictionary * d = [NSMutableDictionary DictionaryWithDictionary:layer.style]; [d setValue:[NSNumber numberWithBool:YES] forKey:@"MyClassName.gradient"]; layer .style = d;)。这对于将任意数据与视图关联可能很有用(例如包含文本字段的单元格的索引路径...)。

(我假设 [NSDictionary DictionaryWithDictionary:nil] 返回空字典,而不是返回 nil 或抛出异常。对于 [NSArray arrayWithArray:nil] 来说,相应的事情是正确的>.)

然而,额外的代码复杂性、性能损失和出错的可能性可能超过内存使用量的小幅下降。如果您有少量视图,每个视图 4 字节并不算多(即使您有负载,4 字节也是单个像素使用的内存!)。

Funfunfun...

There are two layer properties you can use (in either case you have to iterate over the layers):

  • CALayer.name "is used by some layout managers to identify a layer". Set it to something reasonably guaranteed to be unique (e.g. "MyClassName.gradient").
  • CALayer.style is a dictionary. You can use keys which aren't used by CoreAnimation (e.g. NSMutableDictionary * d = [NSMutableDictionary dictionaryWithDictionary:layer.style]; [d setValue:[NSNumber numberWithBool:YES] forKey:@"MyClassName.gradient"]; layer.style = d;). This might be useful to associate arbitrary data with a view (such as the index path of the cell containing a text field...).

(I'm assuming that [NSDictionary dictionaryWithDictionary:nil] returns the empty dictionary instead of returning nil or throwing an exception. The corresponding thing is true for [NSArray arrayWithArray:nil].)

However, the extra code complexity, performance penalty, and chance of getting it wrong probably outweigh the small decrease in memory usage. 4 bytes per view is not that much if you have a handful of views (and even if you have loads, 4 bytes is the memory used by a single pixel!).

倾其所爱 2024-10-10 11:42:56

Swift 有一些非常简单的解决方案:

// SWIFT 4 update
func removeSublayer(_ view: UIView, layerIndex index: Int) {
    guard let sublayers = view.layer.sublayers else {
        print("The view does not have any sublayers.")
        return
    }
    if sublayers.count > index {
        view.layer.sublayers!.remove(at: index)
    } else {
        print("There are not enough sublayers to remove that index.")
    }
}
// Call like so
removeSublayer(view, layerIndex: 0)

只要记住,子层被视为数组,因此如果计数为 2,则索引中的 2 == 1,因此 removeAtIndex(1)

有一大堆可用于编辑子图层的选项。只需在 sublayers!. 之后停止输入并检查它们即可。

Swift has some really simple solutions for this:

// SWIFT 4 update
func removeSublayer(_ view: UIView, layerIndex index: Int) {
    guard let sublayers = view.layer.sublayers else {
        print("The view does not have any sublayers.")
        return
    }
    if sublayers.count > index {
        view.layer.sublayers!.remove(at: index)
    } else {
        print("There are not enough sublayers to remove that index.")
    }
}
// Call like so
removeSublayer(view, layerIndex: 0)

Just remember, the sublayers are treated as an array, so if you have a count of 2, then 2 == 1 in the index, hence removeAtIndex(1).

There are a whole heap of options available for editing sublayers. Simply stop typing after sublayers!. and check them out.

水波映月 2024-10-10 11:42:56

旧帖子..但这可能对某人有帮助...

我删除/替换 CALayer 的实现。使用 Calayer.name 作为 tc。如上所述。

CAGradientLayer *btnGradient = [CAGradientLayer layer];
btnGradient.frame = button.bounds;
btnGradient.name = @"gradient";
btnGradient.colors = nil;
btnGradient.colors = [NSArray arrayWithObjects:
                      (id)[[VOHelper getButtonColor:kSchemeBorder] CGColor],
                      (id)[[VOHelper getButtonColor:kSchemeButton] CGColor],
                      nil];

if ([[[[button.layer sublayers] objectAtIndex:0] name] isEqualToString:btnGradient.name])
{
       [button.layer replaceSublayer:[[button.layer sublayers] objectAtIndex:0] with:btnGradient];
}
else
{
    [button.layer insertSublayer:btnGradient atIndex:0];
}

Old Post.. but this may be helpful for someone...

My implementation of removing/replacing a CALayer. Using the Calayer.name as tc. describes above.

CAGradientLayer *btnGradient = [CAGradientLayer layer];
btnGradient.frame = button.bounds;
btnGradient.name = @"gradient";
btnGradient.colors = nil;
btnGradient.colors = [NSArray arrayWithObjects:
                      (id)[[VOHelper getButtonColor:kSchemeBorder] CGColor],
                      (id)[[VOHelper getButtonColor:kSchemeButton] CGColor],
                      nil];

if ([[[[button.layer sublayers] objectAtIndex:0] name] isEqualToString:btnGradient.name])
{
       [button.layer replaceSublayer:[[button.layer sublayers] objectAtIndex:0] with:btnGradient];
}
else
{
    [button.layer insertSublayer:btnGradient atIndex:0];
}
谜兔 2024-10-10 11:42:56

雨燕4

  self.view.layer.sublayers = self.view.layer.sublayers?.filter { theLayer in
        !theLayer.isKind(of: CAGradientLayer.classForCoder())
  }

Swift 4

  self.view.layer.sublayers = self.view.layer.sublayers?.filter { theLayer in
        !theLayer.isKind(of: CAGradientLayer.classForCoder())
  }
沉睡月亮 2024-10-10 11:42:56

这对我有用 Swift 5

    if let _ = self.layer.sublayers?.first as? CAGradientLayer {
        print("Debug: Gradient sublayer Found.")
        self.layer.sublayers?[0] = gradient
    }
    else {
        print("Debug: Non Gradient Layer Found in Sublayer 0.")
        self.layer.insertSublayer(gradient, at: 0)
    }

This worked for me Swift 5

    if let _ = self.layer.sublayers?.first as? CAGradientLayer {
        print("Debug: Gradient sublayer Found.")
        self.layer.sublayers?[0] = gradient
    }
    else {
        print("Debug: Non Gradient Layer Found in Sublayer 0.")
        self.layer.insertSublayer(gradient, at: 0)
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文