无法同时绘制到多个子类UIView对象。试过很多方法
[编辑]
原来的问题BELOW开始。这里是更多的信息
我一直在这个问题上整天工作,无法找到一个解决方案。我已经创建了一个UIView子类,并将绘图代码剪下来。
-(void)drawRect:(CGRect)rect
{
//// rechargeLevel Drawing
CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64);
UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath];
[rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: endAngle * M_PI/180 clockwise: YES];
[[UIColor redColor] setStroke];
rechargeLevelPath.lineWidth = 4.5;
[rechargeLevelPath stroke];
endAngle++;
if (endAngle > 359) {
endAngle = 1;
}
}
我试过以下所有的东西。
的drawRect:与调用setNeedsDisplay计时器(也试过setNeedsDisplayInRect:
CAShapeLayer与调用绘制的形状的被称为后块内
CAShapeLayer的方法的计时器因为我在想这个计时器正在搞砸东西。
创建了UIView的第二个子类,它的代码都是相同的,但是使用了diff不同的标签。初始化其中的一个仍然不起作用。
我试过两个子类之间的上述方法的组合,但仍然没有。
当您使用相同的上下文启动另一个或其全部时,计时器会停止。我不知道。
我已经创建了一个GitHub存储库和我所做的测试项目。它有一个viewController,它有六个按钮,从两个子类中初始化上述每个方法,并将它们添加到视图中。
的GitHub库是:https://github.com/MoseCode/drawTest
[结束编辑]
原来的问题如下:
试图做定制的drawRect在同一时间的计时器到多个对象绘制。
我有一个自定义UIController(WP_BonusController)设置为接收触摸事件。在触摸控制器5次后,它将禁用事件,直到经过指定的时间。
为了说明充电时间,我从DrawRect绘制了一个圆形路径。我正在使用UIGraphicsGetCurrentContext,然后抚摸新的路径。
我的问题是,当我实例化一堆这些WP_BonusController对象,他们都从UIGraphicsGetCurrentContext共享相同的上下文。我检查了对象的ram分配,它们都是不同的。但是当我在drawRect中放置一个断点:并从UIGraphicsGetCurrentContext中检查CGContextRef时,它们都具有相同的RAM分配。
当我点击bonusController1五次计时器启动并开始在图标周围绘制圆圈。它工作正常。
然后我按下bonusController2五次,它启动它的计时器,但是当它在drawRect中绘制上下文时,我从另一个bonusController1获得相同的上下文。所以绘制的线已经是一半了。
这对任何数量的这些控制器都是一样的。
有没有一种方法可以创建我自己的不使用UIGraphicsGetCurrentContext的干净上下文。我一直在寻找,找不到解决方案。也许我没有正确理解上下文的用法。我需要能够在任何时间和多次同时单独绘制这些控制器。
这里是我的drawRect:即获得由定时器叫:
-(void)drawRect:(CGRect)rect
{
_currentAngle = _currentAngle + 1;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.frame.size.width, self.frame.size.height), NO, 0);
// General Declarations
CGContextRef context = UIGraphicsGetCurrentContext();
// Resize to Target Frame
CGContextSaveGState(context);
CGRect resizedFrame = WP_CustomIconsResizingBehaviorApply(WP_CustomIconsResizingBehaviorAspectFill, CGRectMake(0, 0, 100, 100), [self getImageRect]);
CGContextTranslateCTM(context, resizedFrame.origin.x, resizedFrame.origin.y);
CGContextScaleCTM(context, resizedFrame.size.width/100, resizedFrame.size.height/100);
//// rechargeLevel Drawing
CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64);
UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath];
[rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: _currentAngle * M_PI/180 clockwise: YES];
[WP_CustomIcons.thirdColor setStroke];
rechargeLevelPath.lineWidth = 4.5;
[rechargeLevelPath stroke];
CGContextRestoreGState(context);
refillMeter = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.refillImageView setImage:refillMeter];
}
想通了。最后一个尝试。也许应该是第一次,但是我只是因为某些原因想着定时器。
CALayerAnimation
@implementation ThirdTimerView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//
}
return self;
}
-(UIBezierPath *)samplePath
{
CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64);
UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath];
[rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: 450 * M_PI/180 clockwise: YES];
return rechargeLevelPath;
}
- (void)startAnimation
{
if (self.pathLayer == nil)
{
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [[self samplePath] CGPath];
shapeLayer.strokeColor = [[UIColor redColor] CGColor];
shapeLayer.fillColor = nil;
shapeLayer.lineWidth = 4.5f;
shapeLayer.lineJoin = kCALineJoinBevel;
[self.layer addSublayer:shapeLayer];
self.pathLayer = shapeLayer;
}
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeTimer"];
pathAnimation.duration = 3.0;
pathAnimation.fromValue = @(0.0f);
pathAnimation.toValue = @(1.0f);
[CATransaction setCompletionBlock:^{
[self removeFromSuperview];
}];
[self.pathLayer addAnimation:pathAnimation forKey:@"strokeTimer"];
}
@end
这场平局方法属于一个自定义的UIView实现? –
是的Reinier,它是一种自定义的UIView。它是UIControl的一个子类,我认为它是UIView的一个子类,并认为它应该可以。我花了一天的时间尝试不同的实现,并没有得到任何工作。我要用我试过的东西来更新我的问题。谢谢。 –
由于Irma飓风,我很抱歉自从星期五以来连接到SO,我发现你可以处理欢呼! –