我想繪製一條特定寬度的線。我在網上搜索了一些例子,但我只找到了使用直線的例子。我需要曲線。此外,我需要檢測用戶是否在線內觸摸。使用Objective C和Sprite Kit可以實現這一點嗎?如果有人能提供一個例子嗎?檢測曲線上的水龍頭?
回答
您可以使用UIBezierPath
創建貝塞爾曲線(漂亮的平滑曲線)。您可以爲CAShapeLayer
指定此路徑,並補充說,作爲一個子層到您的視圖:
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 150)];
[path addCurveToPoint:CGPointMake(110, 150) controlPoint1:CGPointMake(40, 100) controlPoint2:CGPointMake(80, 100)];
[path addCurveToPoint:CGPointMake(210, 150) controlPoint1:CGPointMake(140, 200) controlPoint2:CGPointMake(170, 200)];
[path addCurveToPoint:CGPointMake(310, 150) controlPoint1:CGPointMake(250, 100) controlPoint2:CGPointMake(280, 100)];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = 10;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
layer.path = path.CGPath;
[self.view.layer addSublayer:layer];
如果你想隨機了一點,你可以隨機一些曲線。如果你想要一些模糊性,請添加一些陰影。如果你想在兩端是圓的,指定一個圓形的線帽:
UIBezierPath *path = [UIBezierPath bezierPath];
CGPoint point = CGPointMake(10, 100);
[path moveToPoint:point];
CGPoint controlPoint1;
CGPoint controlPoint2 = CGPointMake(point.x - 5.0 - arc4random_uniform(50), 150.0);
for (NSInteger i = 0; i < 5; i++) {
controlPoint1 = CGPointMake(point.x + (point.x - controlPoint2.x), 50.0);
point.x += 40.0 + arc4random_uniform(20);
controlPoint2 = CGPointMake(point.x - 5.0 - arc4random_uniform(50), 150.0);
[path addCurveToPoint:point controlPoint1:controlPoint1 controlPoint2:controlPoint2];
}
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = 5;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor clearColor].CGColor;
layer.path = path.CGPath;
layer.shadowColor = [UIColor redColor].CGColor;
layer.shadowRadius = 2.0;
layer.shadowOpacity = 1.0;
layer.shadowOffset = CGSizeZero;
layer.lineCap = kCALineCapRound;
[self.view.layer addSublayer:layer];
如果你希望它是更不規則,打破這些貝濟耶分成小段,但這個想法將是相同。連接貝塞爾曲線的唯一技巧就是要確保一條曲線的第二個控制點與下一個控制點的第一個控制點一致,否則最終會在曲線中出現尖銳的不連續點。
如果您想檢測用戶是否以及何時點擊它,那就更加複雜。但是,你必須做的是:
使圖像的快照:
- (UIImage *)captureView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 1.0); // usually I'd use 0.0, but we'll use 1.0 here so that the tap point of the gesture matches the pixel of the snapshot if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { BOOL success = [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; NSAssert(success, @"drawViewHierarchyInRect failed"); } else { [view.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
獲取像素的顏色在座標用戶通過識別像素的顏色抽頭用戶點擊。
- (void)handleTap:(UITapGestureRecognizer *)gesture { CGPoint point = [gesture locationInView:gesture.view]; CGFloat red, green, blue, alpha; UIColor *color = [self image:self.image colorAtPoint:point]; [color getRed:&red green:&green blue:&blue alpha:&alpha]; if (green < 0.9 && blue < 0.9 && red > 0.9) NSLog(@"tapped on curve"); else NSLog(@"didn't tap on curve"); }
我在哪裏,以便確定像素抽頭上的用戶是的顏色適於Apple's code for getting the pixel buffer。
// adapted from https://developer.apple.com/library/mac/qa/qa1509/_index.html - (UIColor *)image:(UIImage *)image colorAtPoint:(CGPoint)point { UIColor *color; CGImageRef imageRef = image.CGImage; // Create the bitmap context CGContextRef context = [self createARGBBitmapContextForImage:imageRef]; NSAssert(context, @"error creating context"); // Get image width, height. We'll use the entire image. size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); CGRect rect = {{0,0},{width,height}}; // Draw the image to the bitmap context. Once we draw, the memory // allocated for the context for rendering will then contain the // raw image data in the specified color space. CGContextDrawImage(context, rect, imageRef); // Now we can get a pointer to the image data associated with the bitmap // context. uint8_t *data = CGBitmapContextGetData (context); if (data != NULL) { size_t offset = (NSInteger) point.y * 4 * width + (NSInteger) point.x * 4; uint8_t alpha = data[offset]; uint8_t red = data[offset+1]; uint8_t green = data[offset+2]; uint8_t blue = data[offset+3]; color = [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:alpha/255.0]; } // When finished, release the context CGContextRelease(context); // Free image data memory for the context if (data) { free(data); // we used malloc in createARGBBitmapContextForImage, so free it } return color; } - (CGContextRef) createARGBBitmapContextForImage:(CGImageRef) inImage { CGContextRef context = NULL; CGColorSpaceRef colorSpace; void * bitmapData; size_t bitmapByteCount; size_t bitmapBytesPerRow; // Get image width, height. We'll use the entire image. size_t pixelsWide = CGImageGetWidth(inImage); size_t pixelsHigh = CGImageGetHeight(inImage); // Declare the number of bytes per row. Each pixel in the bitmap in this // example is represented by 4 bytes; 8 bits each of red, green, blue, and // alpha. bitmapBytesPerRow = (pixelsWide * 4); bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); // Use the generic RGB color space. colorSpace = CGColorSpaceCreateDeviceRGB(); // CGColorSpaceCreateDeviceWithName(kCGColorSpaceGenericRGB); NSAssert(colorSpace, @"Error allocating color space"); // Allocate memory for image data. This is the destination in memory // where any drawing to the bitmap context will be rendered. bitmapData = malloc(bitmapByteCount); NSAssert(bitmapData, @"Unable to allocate bitmap buffer"); // Create the bitmap context. We want pre-multiplied ARGB, 8-bits // per component. Regardless of what the source image format is // (CMYK, Grayscale, and so on) it will be converted over to the format // specified here by CGBitmapContextCreate. context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, // bits per component bitmapBytesPerRow, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst); NSAssert(context, @"Context not created!"); // Make sure and release colorspace before returning CGColorSpaceRelease(colorSpace); return context; }
非常感謝你的解釋和你的時間。我在試着你告訴我的。只是一個問題,如果我想改變線條形狀的螺旋。在這種情況下,我將不得不修改方法addCurveToPoint正確嗎? – lyons 2014-10-07 12:30:51
是的,你必須調整你添加的貝塞爾曲線的終點和控制點。請參閱[圖紙和打印指南]中關於貝齊爾的討論(https://developer.apple.com/LIBRARY/IOS/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/BezierPaths/BezierPaths.html#//apple_ref/doc/uid/ TP40010156-CH11-SW1)(儘管它正在討論用於beziers的較低級別的Core Graphics API,但在「向您的路徑添加曲線」部分中的控制點的圖示可能很明顯)。 – Rob 2014-10-07 13:18:40
好的謝謝你的回答最好的問候@Rob – lyons 2014-10-07 13:21:14
- 1. 檢測UITableView背景上的水龍頭
- 2. UIScrollView檢測水龍頭
- 3. 檢測用戶水龍頭
- 4. 檢測背景水龍頭
- 5. 在動畫UIImageView上檢測水龍頭
- 6. 檢測UIWebView內的水龍頭
- 7. Sony Smartwatch - 檢測額外的水龍頭?
- 8. Android Widget檢測水龍頭和雙擊
- 9. iPhone:在MKMapView中檢測水龍頭
- 10. UIScrollView檢測用戶水龍頭
- 11. 如何檢測UITextView下劃線的水龍頭?
- 12. 如何檢測Palm Pre上的手勢區域的水龍頭?
- 13. 如何檢測MKPolylines /覆蓋像Maps.app上的水龍頭?
- 14. 在NSAttributedString中檢測鏈接上的水龍頭
- 15. Unity3d如何檢測android上的水龍頭?
- 16. 檢測UIImageViews上添加到UIScrollView的水龍頭
- 17. 統一檢測球體上的水龍頭
- 18. 如何檢測上表視圖用戶水龍頭
- 19. 在MK ANNOTATION視圖標註氣泡上檢測到水龍頭
- 20. UICollectionView:測量單元水龍頭的力
- 21. 檢測UITextView中的鏈接/數字的水龍頭
- 22. 在iOS7的MKMapView中檢測MKPolygonView的水龍頭
- 23. 離線UIView響應水龍頭
- 24. iPhone +檢測到禁用的水龍頭UIControl
- 25. 菜單檢測遠離其圖標的水龍頭
- 26. 檢測在CAShapeLayer中製作水龍頭的位置
- 27. 在UIScrollView裏面檢測UIImageView的水龍頭
- 28. 檢測貝塞爾路徑內的水龍頭
- 29. 檢測當前視圖外的任何水龍頭
- 30. 如何在視圖中的任何位置檢測水龍頭?
你是什麼意思畫一條線?用戶繪製它?你有沒有想要繪製的特定貝塞爾路徑? – Milo 2014-10-06 23:17:10
嗨,當遊戲開始時,用戶將看到該行,他將使用手指觸摸行。謝謝! – lyons 2014-10-07 12:15:33