剪辑时如何避免覆盖drawRect

Posted

技术标签:

【中文标题】剪辑时如何避免覆盖drawRect【英文标题】:how to avoid overriding drawRect when clipping 【发布时间】:2012-02-17 16:59:15 【问题描述】:

目前我在视图中覆盖drawRect,以便能够使用蒙版剪辑彩色矩形(使用CGContextClipToMaskinside drawRect)。 有时我会改变这个剪裁矩形的颜色。在这种情况下,drawRect 再次被调用,用新颜色重新绘制和裁剪矩形。 现在我不想立即更改颜色,而是对此进行动画处理。问题是,在覆盖 drawRect 时不会执行动画(drawRect 只会被立即调用一次)。

有没有办法执行这个动画,也许通过子类化视图,所以我仍然覆盖超类中的drawRect,但是动画是通过子类执行的,因此超类中的drawRect在期间被执行多次动画?

或者也可以根本不覆盖drawRect,并且仍然能够以某种方式用蒙版剪辑这个矩形? drawRect看起来像这样:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGImageRef maskImage = [[UIImage imageNamed:maskName] CGImage];
CGContextClipToMask(ctx, rect, maskImage);

CGContextSetFillColorWithColor(ctx, self.currentColor);
CGContextFillRect( ctx, rect );

【问题讨论】:

【参考方案1】:

我认为最好使用 CALayer 来掩盖您的视图(不要忘记导入 QuartzCore):

maskLayer.contents = (id)[UIImage imageNamed:maskName].CGImage; // maskLayer is a CALayer
view.layer.mask = maskLayer;

现在假设您的视图控制器中有一个方法 -(void)animate,您已经使用计时器多次执行它,或者使用对 performSelector:withObject:afterDelay 的递归调用。

【讨论】:

太棒了,用你的方法我不必重写 drawRect 所以我终于可以使用动画了。我不必使用计时器或递归执行动画方法,因为我现在可以使用标准的 CoreAnimation。非常感谢!需要注意的一件事是,您必须使用 png 图像或一些颜色清晰的图像(黑白蒙版不再起作用,但这没问题)。此外,您还必须使用 maskLayer.frame = [self bounds]; 将图层框架设置为要屏蔽的视图的边界【参考方案2】:

一种解决方案是使用一个计时器,当颜色发生变化时,该计时器会随着时间的推移重复重绘。当用户选择一种新颜色时,为NSTimer 加注星标,它会触发,例如每秒 10 次。当计时器触发时,将当前颜色更新为从开始颜色到结束颜色的中途,并使视图无效。达到最终颜色后,关闭计时器。

【讨论】:

谢谢,这听起来应该可行,但也有点像重新发明(动画)***。如果没有其他选择,我会使用它。

以上是关于剪辑时如何避免覆盖drawRect的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 iPhone X 上的视图剪辑

使用相同名称时如何避免覆盖列表项?

当切点在超类上但派生类覆盖时,如何避免两次命中切入点?

创建一个精简版,使用多个目标,你如何避免覆盖完整版?

避免在签入或合并时不同开发人员之间的意外覆盖

替换`overflow:hidden`,它不会剪辑中间字符