5

我在我的 .layer 属性中画了几条线UIView。但是有没有办法清理我画的所有线条?

我想清除在我的视图层上绘制的所有内容。

我用以下代码画了一条线:

- (void)drawLine :(UIView *)drawInView :(CGPoint)startPosition :(CGPoint)endPosition
{
    //draw the line
    linePath = CGPathCreateMutable();
    lineShape = [CAShapeLayer layer];

    lineShape.lineWidth = 1.0f;
    lineShape.lineCap = kCALineCapRound;;
    lineShape.strokeColor = [[UIColor whiteColor] CGColor];

    CGPathMoveToPoint(linePath, NULL, startPosition.x, startPosition.y);
    CGPathAddLineToPoint(linePath, NULL, endPosition.x, endPosition.y);

    lineShape.path = linePath;
    CGPathRelease(linePath);
    [drawInView.layer addSublayer:lineShape];
}

我找到了一些代码来删除我绘制的所有子层。

-(void)clearGraph :(UIView *)viewToClear
{
    for (CALayer *layer in viewToClear.layer.sublayers) {
        [layer removeFromSuperlayer];
    }
}

但这将给出一个例外:

2013-08-28 21:10:18.877 ServerInfo[12861:3f03] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <CALayerArray: 0x1f86b3b0> was mutated while being enumerated.'
*** First throw call stack:
(0x336ef3e7 0x3b3ea963 0x336eeec1 0x13f7d 0x158bb 0x340082fb 0x336c4857 0x336c4503 0x336c3177 0x3363623d 0x336360c9 0x33f5a5c3 0x33ffdc45 0x15843 0x34007231 0x3b8370e1 0x3b836fa8)
libc++abi.dylib: terminate called throwing an exception
(lldb) 

我在 NSTread 中调用我的 drawline 方法。(具体的doParsing方法)。

NSThread *myThread =[[NSThread alloc]initWithTarget:self selector:@selector(callTimer) object:nil];
    [myThread start];

- (void)callTimer
{
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(doParsing) userInfo:nil repeats:YES];
    [runLoop run];
}
4

4 回答 4

14

删除 UIView 的所有子层的更简单的方法是将其 sublayers 属性设置为 nil

viewToClear.layer.sublayers = nil;
于 2014-10-28T10:17:52.283 回答
10

Call CGContextClearRect with the current context and the rect to clear.


Based on your updated code, you aren't actually drawing anything. You're actually adding sub layers. So, to remove any previous line you need to remove the sub layer. You will need to come up with a way of finding the appropriate sub layer (maybe hold a property, maybe by tag) and then you can remove it just like you add it.


Don't perform the loop yourself, get the array to do it:

[viewToClear.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
于 2013-08-28T17:58:39.200 回答
4

我使用了与 Erwan 的回复非常相似的东西。但事实证明我不需要“层”部分。这对我有用。小而有效。

imageLayer.sublayers = nil;

于 2015-07-15T15:04:51.897 回答
0

对于某些人来说,它可能会崩溃,你只需要这样做

2019-09-14 00:43:35.388050+0300 SummonersRift[17980:616553] [View] View has lost track of its superview, most likely through unsupported use of CALayer API on the view's layer. If this isn't a crash yet, it will be in the near future. 
    Problem view: <UIButton: 0x7f9c2491c7a0; frame = (54 54; 42 42); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600002a16860>>
    Expected parent: <UIView: 0x7f9c24918db0; frame = (0 0; 150 150); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600002a16840>>
Break on UIViewReportBrokenSuperviewChain to debug.
2019-09-14 00:43:35.388453+0300 SummonersRift[17980:616553] [LayoutConstraints] View hierarchy unprepared for constraint.
    Constraint: <NSLayoutConstraint:0x6000009f65d0 UIButton:0x7f9c2491c7a0.centerX == UIView:0x7f9c24918db0.centerX   (active)>
    Container hierarchy: 
<UIView: 0x7f9c24918db0; frame = (0 0; 150 150); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600002a16840>>
    View not found in container hierarchy: <UIButton: 0x7f9c2491c7a0; frame = (54 54; 42 42); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600002a16860>>
    That view's superview: NO SUPERVIEW
2019-09-14 00:43:35.401892+0300 SummonersRift[17980:616553] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view.  Does the constraint reference something from outside the subtree of the view?  That's illegal. constraint:<NSLayoutConstraint:0x6000009f65d0 UIButton:0x7f9c2491c7a0.centerX == UIView:0x7f9c24918db0.centerX   (active)> view:<UIView: 0x7f9c24918db0; frame = (0 0; 150 150); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600002a16840>>'
*** First throw call stack:

解决这个问题

    while let subview = draw_view.subviews.last {
        subview.removeFromSuperview()
    }

    self.draw_view.layer.sublayers = nil
于 2019-09-13T21:44:22.960 回答