2

我有一个名为 MNTRectangle 的类,它是 UIImage 的子类。我已经重写了此类的 drawRect 方法以在图像上绘制边框(使用它的框架)。我有它,所以当用户在名为 DocumentView 的类(UIView 的子类)上开始平移/拖动手势时,它会将 MNTRectangle 的实例作为子视图添加到 DocumentView 的实例中。随着用户继续拖动 MNTRectangle 被调整大小。问题是 MNTRectangle 最后显示为纯黑色,我尝试清除图形上下文以及在绘制边框之前保存上下文并在绘制边框后恢复上下文。无论我似乎尝试什么,我都无法清除 MNTRectangle 并仅在调整大小时显示边框。

这是我的 MNTRectangle 类的代码:

@implementation MNTRectangle

- (id)init
{
    self = [super init];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (void)setup
{
    [self setBackgroundColor:[UIColor clearColor]];
}

- (void)drawRect:(CGRect)rect
{
    // Get graphics context
    CGContextRef context = UIGraphicsGetCurrentContext();

//    CGContextSaveGState(context);

//    CGContextClearRect(context, rect);

    // Draw border
    CGContextSetLineWidth(context, 4.0);
    [[UIColor blackColor] setStroke];
    CGContextStrokeRect(context, rect);

//    CGContextRestoreGState(context);
}

这是 DocumentView 中用于 UIView 上的平移/拖动处理的代码:

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
         _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    }

    return self;
}

- (void)handlePan:(UIPanGestureRecognizer *)sender
{
    if ([sender state] == UIGestureRecognizerStateBegan)
    {
        _startPanPoint = [sender locationInView:self];

        MNTRectangle *rectangle = [[MNTRectangle alloc] initWithFrame:CGRectMake(_startPanPoint.x, _startPanPoint.y, 1, 1)];
        [_objects addObject:rectangle];
        _currentPanObject = rectangle;
        [self addSubview:rectangle];
    }
    else if ([sender state] == UIGestureRecognizerStateChanged)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
    }
    else if ([sender state] == UIGestureRecognizerStateEnded)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
    }
}

对此的任何帮助将不胜感激。

4

3 回答 3

2

我终于弄明白了。在handlePan:我设置我丢失的矩形框架之后的方法中[rectangle setNeedsDisplay];

现在我的 DocumentView 代码如下所示:

-(id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];

    if (self)
    {
         _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    }

    return self;
}

- (void)handlePan:(UIPanGestureRecognizer *)sender
{
   if ([sender state] == UIGestureRecognizerStateBegan)
   {
        _startPanPoint = [sender locationInView:self];

        MNTRectangle *rectangle = [[MNTRectangle alloc] initWithFrame:CGRectMake(_startPanPoint.x, _startPanPoint.y, 1, 1)];
        [_objects addObject:rectangle];
        _currentPanObject = rectangle;
        [self addSubview:rectangle];
    }
    else if ([sender state] == UIGestureRecognizerStateChanged)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
        [rectangle setNeedsDisplay];
    }
    else if ([sender state] == UIGestureRecognizerStateEnded)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
        [rectangle setNeedsDisplay];
    }
}
于 2012-12-08T00:36:04.733 回答
0

你会想打电话[super drawRect:rect]

于 2012-12-07T22:36:05.213 回答
0

为了向任何阅读的人澄清,调用[rectangle setNeedsDisplay];是必要的,因为您正在覆盖,因此需要告诉,drawRect:的这个子类在其内部变量已更改后手动重绘自身。UIViewMNTRectangle

此函数在继承自 的标准对象上自动调用UIView,但由于您创建了自定义对象,如果您有一些MNTRectangle需要重绘的特殊行为,则需要手动调用它。

更多文档在这里

于 2012-12-08T01:03:29.823 回答