【发布时间】:2017-09-07 20:35:56
【问题描述】:
[编辑]
原始问题从下面开始。这里有更多信息
我整天都在处理这个问题,但找不到解决方案。我对 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 的第二个子类,代码相同,但标签不同。初始化其中一个仍然不起作用。
我已经在两个子类之间尝试了上述方法的组合,但仍然没有。
计时器在您启动另一个计时器时停止,或者它全部使用相同的上下文。我不知道。
我已经使用我制作的测试项目创建了一个 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];
}
【问题讨论】:
-
这个draw方法属于自定义的UIView实现吗?
-
是的 Reinier,它有点像自定义 UIView。它是 UIControl 的子类,我认为它是 UIView 的子类,并且认为应该没问题。我花了一天时间尝试不同的实现,但无法让它们中的任何一个工作。我将用我尝试过的其他方法来更新我的问题。谢谢。
-
很抱歉,由于 Irma 飓风,我从星期五开始就无法连接到 SO,我知道你可以应付欢呼声!
标签: ios core-graphics drawrect cgcontext