2012-12-07 7 views
2

У меня есть класс под названием MNTRectangle, который является подклассом UIImage. Я переопределил метод drawRect этого класса, чтобы нарисовать границу изображения (используя его фрейм). У меня это есть, когда пользователь начинает жест панорамирования/перетаскивания в классе под названием DocumentView (подкласс UIView), он добавляет экземпляр MNTRectangle в качестве подзапроса экземпляру DocumentView. По мере того, как пользователь продолжает перетаскивать, MNTRectangle изменяется. Проблема в том, что MNTRectangle выглядит сплошным черным в конце, я попытался очистить контекст графики, а также сохранить контекст, прежде чем рисовать границу и восстановить контекст после рисования границы. Независимо от того, что я, кажется, пытаюсь, я не могу заставить MNTRectangle очистить и просто показать границу при изменении размера.UIImage Resize drawRect Заполнение фона черным

Вот код для моего класса 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)]; 
    } 
} 

Любая помощь с этим было бы значительно оценили.

+0

Попробуйте установить свойство 'opaque' вашего подкласса' NO'. По умолчанию это 'YES', что заставляет систему рисования и компоновки делать некоторые предположения. – warrenm

+0

Я пробовал это, а также не устанавливал свойство 'clearsContextBeforeDrawing'' YES' без всякой удачи. –

ответ

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]; 
    } 
} 
0

Вы собираетесь хотите позвонить [super drawRect:rect]

+0

Я предполагаю, что вы имеете в виду добавление супервызов в метод drawRect для MNTRectangle. Это не исправляет (я это пробовал), и я не думаю, что мне нужно вызвать супер метод в drawRect, так как все, что я рисую, я реализую сам. –

0

Чтобы уточнить для тех, кто читает, вызывая [rectangle setNeedsDisplay]; необходимо потому, что вы перекрывая drawRect: и, таким образом, этот подклассу UIView, MNTRectangle, нужно сказать, вручную перерисовать себя после изменения внутренних переменных.

Эта функция вызывается автоматически на стандартных объектах, которые наследуются от UIView, но так как вы создали пользовательский объект, вам нужно будет называть его вручную, если у вас есть специальное поведение в MNTRectangle, которое требует перерисовки.

Дополнительная документация here.

Смежные вопросы