【问题标题】:iOS adding subViews and subLayers multiple timesiOS 多次添加 subViews 和 subLayers
【发布时间】:2017-01-16 04:29:19
【问题描述】:

我有一个构建界面的方法,在主 UIView 中添加了一个 subView 和一些 subLayers(下面代码中的 containerView):

- (void)gradeAnimation:(NSNumber*)grade withDuration:(double)duration {

scoreLabel = [[UICountingLabel alloc] init];
scoreLabel.frame = CGRectOffset(_gradeLabel.frame, 0, 5);
[_containerView addSubview:scoreLabel];

// Other code

UIBezierPath *circlePathMin = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_gradientView.center.x, _gradientView.center.y) radius:_gradientView.frame.size.height * 0.5 - 5 startAngle:-M_PI_4*1.2 endAngle:angle1 clockwise:YES];
circleMin               = [CAShapeLayer layer];
circleMin.path          = circlePathMin.CGPath;
circleMin.lineCap       = kCALineCapButt;
circleMin.fillColor     = [UIColor clearColor].CGColor;
circleMin.lineWidth     = 14;
circleMin.strokeColor = [UIColor colorWithRed:246.0/255.0f green:246.0f/255.0f blue:246.0f/255.0f alpha:0.7f].CGColor;
circleMin.zPosition     = 3;
[_containerView.layer addSublayer:circleMin];

UIBezierPath *circlePathMax = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_gradientView.center.x, _gradientView.center.y) radius:_gradientView.frame.size.height * 0.5 - 5 startAngle:angle2 endAngle:5*M_PI_4*1.2 clockwise:YES];
circleMax               = [CAShapeLayer layer];
circleMax.path          = circlePathMax.CGPath;
circleMax.lineCap       = kCALineCapButt;
circleMax.fillColor     = [UIColor clearColor].CGColor;
circleMax.lineWidth     = 14;
circleMax.strokeColor = [UIColor colorWithRed:246.0/255.0f green:246.0f/255.0f blue:246.0f/255.0f alpha:0.7f].CGColor;
circleMax.zPosition     = 3;
[_containerView.layer addSublayer:circleMax];

UIBezierPath *circlePathMiddle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_gradientView.center.x, _gradientView.center.y) radius:_gradientView.frame.size.height * 0.5 - 5 startAngle:angle1+offsetRight endAngle:angle2+offsetLeft clockwise:YES];
circleMiddle               = [CAShapeLayer layer];
circleMiddle.path          = circlePathMiddle.CGPath;
circleMiddle.lineCap       = kCALineCapButt;
circleMiddle.fillColor     = [UIColor clearColor].CGColor;
circleMiddle.lineWidth     = 14;
circleMiddle.strokeColor = [UIColor colorWithRed:246.0/255.0f green:246.0f/255.0f blue:246.0f/255.0f alpha:0.7f].CGColor;
circleMiddle.zPosition     = 3;
[_containerView.layer addSublayer:circleMiddle];
}

我的问题是,如果我多次调用此方法,每次都会添加子视图和子图层,并且不会像我想要的那样重绘它们。为什么会这样?

【问题讨论】:

    标签: ios objective-c uiview subview


    【解决方案1】:

    我们只说一个对象,scoreLabel 是 UICountingLabel 的一个对象。每次您调用gradeAnimation: withDuration: 方法时,您都在创建一个新对象并将其添加到您的视图中。

    您可以获取一个属性,然后启动并添加一次视图,在该方法中您可以更改对象的位置或其他内容。

    如果您不想更改当前方法,则在调用该方法之前,您必须从视图中删除以前的对象。这样一次我们在您的视图中只会看到一个对象。

    【讨论】:

    • 全局对象(在@implementation 中定义)但我每次都在启动它们。如果我只在它工作后执行此操作,谢谢。
    • 很高兴能提供帮助。 :-)
    【解决方案2】:

    如果您使用addSublayeraddSubview,那么它肯定会为containerView 添加新图层或新视图。如果您不想每次都添加它并且想要重绘(我的意思是新实例 - 正如我从您所讨论的重绘单词中所理解的那样),请添加以下行,

     _containerView = [[UIView alloc]initWithFrame:self.view.bounds]; // you can set your desired frame 
    

    gradeAnimation 方法中作为第一行。所以它会创建每次的新实例。或者您可以先删除sublayerssubviews 然后添加新的!!!或者您可以在方法中创建新的containerView,并可以为其添加子视图和图层,并可以将其分配给_containerView

    【讨论】:

      【解决方案3】:

      首先从 containerView 中移除所有子层。在方法的开头添加以下代码。

      for (CALayer *layer in _containerView) {
          [layer removeFromSuperlayer];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        • 2018-10-12
        • 1970-01-01
        相关资源
        最近更新 更多