UIView子类重绘UIBezierPath而不重绘整个视图
UIView subclass redraw UIBezierPath without redrawing entire view
我有一个应用程序允许用户在图像上绘制,以便最终将其裁剪到绘制的路径。不幸的是,虽然它很慢。原因是它依赖 [self setNeedsDisplay]
来刷新 UIBezierPath,这会导致图像重绘并影响性能。有没有一种方法可以在每次调用 setNeedsDisplay
时不重绘 UIImage 的情况下实现这一点?或者更好的方法来实现整个事情?感谢所有帮助!下面是我的 UIView 子类:
#import "DrawView.h"
@implementation DrawView
{
UIBezierPath *path;
}
- (id)initWithCoder:(NSCoder *)aDecoder // (1)
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:NO]; // (2)
[self setBackgroundColor:[UIColor whiteColor]];
path = [UIBezierPath bezierPath];
[path setLineWidth:2.0];
}
return self;
}
- (void)drawRect:(CGRect)rect // (5)
{
[self.EditImage drawInRect:self.bounds];
[[UIColor blackColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p]; // (4)
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
@end
我的一个应用程序也遇到了这个问题 - 正如您提到的,它正在调用 drawInRect
,这导致了性能问题。我解决它的方法是将背景图像视图和需要多次重新绘制的视图分离到它们自己的 classes.
所以在这种情况下,您将创建一个 class 来代表您的背景图片,然后将您的 "drawView" 添加到具有透明背景的视图中。这样,所有绘图都将由 drawView 处理,但背景图像将保持静态。用户完成绘制后,背景视图可以根据 drawView 提供的路径自行裁剪。
我有一个应用程序允许用户在图像上绘制,以便最终将其裁剪到绘制的路径。不幸的是,虽然它很慢。原因是它依赖 [self setNeedsDisplay]
来刷新 UIBezierPath,这会导致图像重绘并影响性能。有没有一种方法可以在每次调用 setNeedsDisplay
时不重绘 UIImage 的情况下实现这一点?或者更好的方法来实现整个事情?感谢所有帮助!下面是我的 UIView 子类:
#import "DrawView.h"
@implementation DrawView
{
UIBezierPath *path;
}
- (id)initWithCoder:(NSCoder *)aDecoder // (1)
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:NO]; // (2)
[self setBackgroundColor:[UIColor whiteColor]];
path = [UIBezierPath bezierPath];
[path setLineWidth:2.0];
}
return self;
}
- (void)drawRect:(CGRect)rect // (5)
{
[self.EditImage drawInRect:self.bounds];
[[UIColor blackColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p]; // (4)
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
@end
我的一个应用程序也遇到了这个问题 - 正如您提到的,它正在调用 drawInRect
,这导致了性能问题。我解决它的方法是将背景图像视图和需要多次重新绘制的视图分离到它们自己的 classes.
所以在这种情况下,您将创建一个 class 来代表您的背景图片,然后将您的 "drawView" 添加到具有透明背景的视图中。这样,所有绘图都将由 drawView 处理,但背景图像将保持静态。用户完成绘制后,背景视图可以根据 drawView 提供的路径自行裁剪。