2015-08-07 1 views
0

J'ai une coutume UIView Je dessine, et dans la fonction drawRect je crée une forme de cercle (avec un centre creux, donc l'image d'un beignet) comme UIBezierPath.Comment créer un dessin UIImage avec drawInRect à l'aide d'un UIBezierPath?

Je veux ensuite utiliser cette forme UIBezierPath/cercle comme masque lorsque je dessine mon UIImage avec drawInRect. Donc, à la fin, je vais avoir une forme de beignet avec un fond d'image.

je crée le cercle/UIBezierPath comme suit:

let context = UIGraphicsGetCurrentContext() 
let progress = CGFloat(1.0) 
let diameter = CGFloat(32.0) 

let gapExpression: CGFloat = diameter * CGFloat(M_PI) 
let dashExpression: CGFloat = progress * diameter * CGFloat(M_PI) 

CGContextSaveGState(context) 
CGContextTranslateCTM(context, 19, 19) 
CGContextRotateCTM(context, -270 * CGFloat(M_PI)/180) 

var circlePath = UIBezierPath() 
circlePath.moveToPoint(CGPointMake(-16, 0)) 
circlePath.addCurveToPoint(CGPointMake(0, -16), controlPoint1: CGPointMake(-16, -8.84), controlPoint2: CGPointMake(-8.84, -16)) 
circlePath.addCurveToPoint(CGPointMake(16, 0), controlPoint1: CGPointMake(8.84, -16), controlPoint2: CGPointMake(16, -8.84)) 
circlePath.addCurveToPoint(CGPointMake(0, 16), controlPoint1: CGPointMake(16, 8.84), controlPoint2: CGPointMake(8.84, 16)) 
circlePath.addCurveToPoint(CGPointMake(-16, 0), controlPoint1: CGPointMake(-8.84, 16), controlPoint2: CGPointMake(-16, 8.84)) 
circlePath.closePath() 
circlePath.lineCapStyle = kCGLineCapRound; 

UIColor.grayColor().setStroke() 
circlePath.lineWidth = 5 
CGContextSaveGState(context) 
CGContextSetLineDash(context, 0, [dashExpression, gapExpression], 2) 
circlePath.stroke() 
CGContextRestoreGState(context) 

Qui, si je viens dans mon drawRect il produit une forme cercle/beignet.

Cependant, je dois aussi UIImage:

let image = UIImage(named: "test-shape") 

que je tire à l'aide drawInRect, mais je veux que l'image soit masquée par la UIBezierPath ci-dessus.

Comment est-ce que j'accomplirais ceci?

Répondre

0

Enregistrez le contexte, ajoutez un clip, définissez l'échelle et dessinez l'image.

Cela devrait être proche:

circlePath.lineCapStyle = kCGLineCapRound;  // existing 

// add these lines 
CGContextSaveGState(context) 
circlePath.addClip() 
CGContextScaleCTM(context, 1, -1) 
CGContextDrawTiledImage(context, CGRectMake(0, 0, test-shape.size.width, test-shape.size.height), test-shape.CGImage) 
CGContextRestoreGState(context) 

UIColor.grayColor().setStroke()     //existing 

Edit pour ajouter autre: Ceci dessine un beignet et il remplit avec l'image. Mais le trait de ligne ne va probablement pas avoir l'effet dont vous avez besoin. Peut-être que cela peut aider d'une certaine façon.

let context = UIGraphicsGetCurrentContext() 

let testshape = UIImage(named: "testshape.png")! 

var circlePath = UIBezierPath() 
circlePath.moveToPoint(CGPointMake(9.5, 2.5)) 
circlePath.addCurveToPoint(CGPointMake(6.1, 3.38), controlPoint1: CGPointMake(8.27, 2.5), controlPoint2: CGPointMake(7.11, 2.82)) 
circlePath.addCurveToPoint(CGPointMake(2.5, 9.5), controlPoint1: CGPointMake(3.95, 4.58), controlPoint2: CGPointMake(2.5, 6.87)) 
circlePath.addCurveToPoint(CGPointMake(9.5, 16.5), controlPoint1: CGPointMake(2.5, 13.37), controlPoint2: CGPointMake(5.63, 16.5)) 
circlePath.addCurveToPoint(CGPointMake(16.5, 9.5), controlPoint1: CGPointMake(13.37, 16.5), controlPoint2: CGPointMake(16.5, 13.37)) 
circlePath.addCurveToPoint(CGPointMake(9.5, 2.5), controlPoint1: CGPointMake(16.5, 5.63), controlPoint2: CGPointMake(13.37, 2.5)) 
circlePath.closePath() 
circlePath.moveToPoint(CGPointMake(19, 9.5)) 
circlePath.addCurveToPoint(CGPointMake(9.5, 19), controlPoint1: CGPointMake(19, 14.75), controlPoint2: CGPointMake(14.75, 19)) 
circlePath.addCurveToPoint(CGPointMake(0, 9.5), controlPoint1: CGPointMake(4.25, 19), controlPoint2: CGPointMake(-0, 14.75)) 
circlePath.addCurveToPoint(CGPointMake(3.88, 1.84), controlPoint1: CGPointMake(0, 6.36), controlPoint2: CGPointMake(1.53, 3.57)) 
circlePath.addCurveToPoint(CGPointMake(9.5, 0), controlPoint1: CGPointMake(5.45, 0.68), controlPoint2: CGPointMake(7.4, 0)) 
circlePath.addCurveToPoint(CGPointMake(19, 9.5), controlPoint1: CGPointMake(14.75, 0), controlPoint2: CGPointMake(19, 4.25)) 
circlePath.closePath() 
circlePath.lineCapStyle = kCGLineCapRound; 

CGContextSaveGState(context) 
circlePath.addClip() 
CGContextScaleCTM(context, 1, -1) 
CGContextDrawTiledImage(context, CGRectMake(0, 0, testshape.size.width, testshape.size.height), testshape.CGImage) 
CGContextRestoreGState(context) 

donut

Si vous voulez juste un demi-cercle, voici un exemple rapide de la façon de tirer cela. Utilisez juste cela comme masque. Tournez au besoin.

let color = UIColor(red: 0.742, green: 0.000, blue: 1.000, alpha: 1.000) 

var bezierPath = UIBezierPath() 
bezierPath.moveToPoint(CGPointMake(56, 45)) 
bezierPath.addCurveToPoint(CGPointMake(31, 70), controlPoint1: CGPointMake(56, 58.81), controlPoint2: CGPointMake(44.81, 70)) 
bezierPath.addCurveToPoint(CGPointMake(26, 65), controlPoint1: CGPointMake(28.24, 70), controlPoint2: CGPointMake(26, 67.76)) 
bezierPath.addCurveToPoint(CGPointMake(31, 60), controlPoint1: CGPointMake(26, 62.24), controlPoint2: CGPointMake(28.24, 60)) 
bezierPath.addCurveToPoint(CGPointMake(46, 45), controlPoint1: CGPointMake(39.28, 60), controlPoint2: CGPointMake(46, 53.28)) 
bezierPath.addCurveToPoint(CGPointMake(31, 30), controlPoint1: CGPointMake(46, 36.72), controlPoint2: CGPointMake(39.28, 30)) 
bezierPath.addCurveToPoint(CGPointMake(26, 25), controlPoint1: CGPointMake(28.24, 30), controlPoint2: CGPointMake(26, 27.76)) 
bezierPath.addCurveToPoint(CGPointMake(29.45, 20.24), controlPoint1: CGPointMake(26, 22.78), controlPoint2: CGPointMake(27.45, 20.9)) 
bezierPath.addCurveToPoint(CGPointMake(31, 20), controlPoint1: CGPointMake(29.94, 20.09), controlPoint2: CGPointMake(30.46, 20)) 
bezierPath.addCurveToPoint(CGPointMake(56, 45), controlPoint1: CGPointMake(44.81, 20), controlPoint2: CGPointMake(56, 31.19)) 
bezierPath.closePath() 
color.setFill() 
bezierPath.fill() 

half circle with rounded ends

+0

Je l'ai fait, et le résultat a fini avec la bordure circulaire grise et l'image à l'intérieur du cercle (l'image est juste un carré violet). Voici à quoi il ressemble: http://i.imgur.com/bMnnf8p.png, et je cherche ceci: http://i.imgur.com/SEDdfNT.png où le violet est masqué par la forme de beignet . –

+0

Oh, je vois ce que vous essayez de faire. Vous essayez d'utiliser la ligne comme masque. Je ne pense pas que tu puisses faire ça. Vous devez probablement dessiner un cercle dans un cercle et utiliser l'image comme remplissage. Laissez-moi mettre à jour répondre ... – picciano

+0

Eh bien, désolé. J'ai joué avec et j'ai pu obtenir le violet pour remplir correctement la forme, mais ce que vous faites avec les tirets ne va évidemment pas fonctionner maintenant. Je vais l'ajouter à la réponse ci-dessus, peut-être que ce sera utile. – picciano