在iOS子视图上绘制矩形触摸

问题描述:

我试图将我在可可中创建的Sudoku应用程序移植到iOS中,并且我无法将我在Mac应用程序中的mouseDown事件转换为iOS上的touchBegan事件。在iOS子视图上绘制矩形触摸

我有一个在父视图中创建的子视图,它具有网格绘制和Sudoku游戏的所有初始值。每当我试图挖掘在模拟器空方以更新的价值,我的控制台给了我这些错误:

Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextSetFillColorWithColor: invalid context 0x0 
Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextSaveGState: invalid context 0x0 
Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextSetFlatness: invalid context 0x0 
Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextAddPath: invalid context 0x0 
Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextDrawPath: invalid context 0x0 
Mar 24 14:59:56 Macintosh-94.local SudokiOS[95817] <Error>: CGContextRestoreGState: invalid context 0x0 

这里是我的Mac应用程序的(工作)代码:

//SudokuView.m 
-(void)paintSelectionRectangle 
{ 
    CGFloat thirdWidth = self.bounds.size.width/3.0; 
    CGFloat thirdHeight = self.bounds.size.height/3.0; 
    CGFloat ninthWidth = thirdWidth/3.0; 
    CGFloat ninthHeight = thirdHeight/3.0; 

    NSRect selectionRect = NSMakeRect(_selectionCellX * thirdWidth + _selectionX * ninthWidth, 
             _selectionCellY * thirdHeight + _selectionY * ninthHeight, 
             ninthWidth, ninthHeight); 

    NSColor* selectionColor = [NSColor colorWithSRGBRed: 0.0 green: 0.0 blue: 1.0 
           alpha: 0.5]; 
    [selectionColor setFill]; 

    NSBezierPath* selectionPath = [NSBezierPath bezierPathWithRoundedRect: selectionRect 
                    xRadius: (ninthWidth/4.0) 
                    yRadius: (ninthHeight/4.0)]; 
    [selectionPath fill]; 
} 

- (void)drawRect:(NSRect)dirtyRect 
{ 

    ... 

    if(_haveSelection) 
    { 
     [self paintSelectionRectangle]; 
    } 
    ... 
} 
. 
. 
. 
-(void)mouseDown:(NSEvent *)event 
{ 
    NSPoint location = [event locationInWindow]; 
    CGFloat thirds = self.bounds.size.width/3; 
    CGFloat ninths = thirds/3; 

    _selectionCellX = (UInt32)(location.x/thirds); 
    _selectionCellY = (UInt32)(location.y/thirds); 
    _selectionX = (UInt32)((location.x - (_selectionCellX * thirds))/ninths); 
    _selectionY = (UInt32)((location.y - (_selectionCellY * thirds))/ninths); 

    _haveSelection = YES; 


    if ([self._windowController isOriginalValueAtCellX:_selectionCellX andCellY:_selectionCellY xIndex:_selectionX yIndex:_selectionY] == NO) 
    { 
     _haveSelection = YES; 
    } 
    else 
    { 
     _haveSelection = NO; 
    } 
    [self setNeedsDisplay:YES]; 
} 

而这就是没有在iOS应用

//SudokiOSViewController.m 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
    UITouch* touch = [[event allTouches] anyObject]; 
    CGPoint location = [touch locationInView:self.sudokuSubview]; 
    CGFloat thirds = sudokuSubview.bounds.size.width/3; 
    CGFloat ninths = thirds/3; 


    _selectionCellX = (UInt32)(location.x/thirds); 
    _selectionCellY = (UInt32)(location.y/thirds); 
    _selectionX = (UInt32)((location.x - (_selectionCellX * thirds))/ninths); 
    _selectionY = (UInt32)((location.y - (_selectionCellY * thirds))/ninths); 
    _haveSelection = YES; 
    if ([ourView._ourViewController isOriginalValueAtCellX:_selectionCellX andCellY:_selectionCellY xIndex:_selectionX yIndex:_selectionY] == NO) 
    { 
     _haveSelection = YES; 
    } 
    else 
    { 
     _haveSelection = NO; 
    } 

} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self touchesBegan:touches withEvent:event]; 
    [sudokuSubview setNeedsDisplay]; 
    [self paintSelectionRectangle]; 
} 

我有困难的时候,我的理解是否应该只使用touchBegan和touchEnded或UIGestureRecognizer合作。我也不明白为什么要调用CGContext。任何帮助,将不胜感激。谢谢!

UPDATE:作为mrueg建议,这里是paintselectionrectangle iOS的代码:

-(void)paintSelectionRectangle 
{ 
    CGFloat thirdWidth = self.bounds.size.width/3.0; 
    CGFloat thirdHeight = self.bounds.size.height/3.0; 
    CGFloat ninthWidth = thirdWidth/3.0; 
    CGFloat ninthHeight = thirdHeight/3.0; 

    CGRect selectionRect = CGRectMake(_selectionCellX * thirdWidth + _selectionX * ninthWidth, 
             _selectionCellY * thirdHeight + _selectionY * ninthHeight, 
             ninthWidth, ninthHeight); 

    UIColor* selectionColor = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:0.5]; 
    [selectionColor setFill]; 

    UIBezierPath* selectionPath = [UIBezierPath bezierPathWithRoundedRect:selectionRect cornerRadius:(ninthWidth/4.0)]; 
    [selectionPath fill]; 
} 
+0

您应该显示'paintSelectionRectangle'的iOS版本,因为这可能是错误的地方。 – mrueg 2013-03-24 22:33:23

+0

已编辑。现在显示。 – 2013-03-24 22:42:47

你不应该在touchesEnded:withEvent:调用paintSelectionRectangle。此方法执行绘制操作,并且您没有图形上下文。只需发送setNeedsDisplay到需要重绘的视图。

另外我认为手动调用touchesBegan:withEvent:是一个坏主意。

编辑:我仔细看了一下你的代码以及你试图达到的目标。我会创建一个绘制选择矩形的UIView子类。只需填写与贝塞尔路径的整个范围:

-(void)drawRect:(CGRect)rect 
{ 
    UIColor* selectionColor = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:0.5]; 
    [selectionColor setFill]; 

    CGRect roundedrect = self.bounds; 
    CGFloat cornerRadius = self.bounds.size.width/36; 
    UIBezierPath* selectionPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect 
                  cornerRadius:cornerRadius]; 
    [selectionPath fill]; 
} 

加入这一观点的一个实例,以您的主视图及hidden属性设置为YES。

touchesEnded:withEvent:确定选择矩形,设置选择视图的帧并设置hidden为NO,如果检测到选择:

CGRect selectionRect = CGRectMake(_selectionCellX * thirdWidth + _selectionX * ninthWidth, 
            _selectionCellY * thirdHeight + _selectionY * ninthHeight, 
            ninthWidth, ninthHeight); 
[selectionSubview setFrame: selectionRect]; 

[selectionSubview setHidden: !_haveSelection]; 

如果你喜欢你也可以使用CoreAnimation动画帧改变。

+0

我试着将'paintSelectionRectangle'移出'touchesEnded'并返回到'touchesBegan'并仍然出现CGContext错误。 你能解释为什么手动调用'touchesBegan:withEvent:'是个坏主意吗? – 2013-03-24 22:41:55

+0

他意味着你应该将'paintSelectionRectangle'移动到'drawRect:',而不是把'setNeedsDisplay'调用到'touchesEnded:withEvent:'中。 – mrueg 2013-03-24 22:50:34

+0

好的,我认为我们正在走上正轨。这样就停止了CGContext错误出现在调试器中,但仍然没有出现选择矩形。 – 2013-03-24 22:57:31