2013-03-24 124 views
0

我試圖將我在可可中創建的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

回答

0

你不應該在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