2010-05-14 13 views

Odpowiedz

55

Nie ma paczkowane sposobem na to, trzeba połączyć łuki w tym celu, jabłka quartzdemo projekt pojawi się kod, aby to zrobić, jest tu odniesienie Quartz Demo a oto kod zapewniają

// As a bonus, we'll combine arcs to create a round rectangle! 

// Drawing with a white stroke color 
CGContextRef context=UIGraphicsGetCurrentContext() 
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); 

// If you were making this as a routine, you would probably accept a rectangle 
// that defines its bounds, and a radius reflecting the "rounded-ness" of the rectangle. 
CGRect rrect = CGRectMake(210.0, 90.0, 60.0, 60.0); 
CGFloat radius = 10.0; 
// NOTE: At this point you may want to verify that your radius is no more than half 
// the width and height of your rectangle, as this technique degenerates for those cases. 

// In order to draw a rounded rectangle, we will take advantage of the fact that 
// CGContextAddArcToPoint will draw straight lines past the start and end of the arc 
// in order to create the path from the current position and the destination position. 

// In order to create the 4 arcs correctly, we need to know the min, mid and max positions 
// on the x and y lengths of the given rectangle. 
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); 
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); 

// Next, we will go around the rectangle in the order given by the figure below. 
//  minx midx maxx 
// miny 2  3  4 
// midy 1 9    5 
// maxy 8  7  6 
// Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't 
// form a closed path, so we still need to close the path to connect the ends correctly. 
// Thus we start by moving to point 1, then adding arcs through each pair of points that follows. 
// You could use a similar tecgnique to create any shape with rounded corners. 

// Start at 1 
CGContextMoveToPoint(context, minx, midy); 
// Add an arc through 2 to 3 
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); 
// Add an arc through 4 to 5 
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); 
// Add an arc through 6 to 7 
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); 
// Add an arc through 8 to 9 
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); 
// Close the path 
CGContextClosePath(context); 
// Fill & stroke the path 
CGContextDrawPath(context, kCGPathFillStroke); 
+3

Jeśli ktoś zastanawiał się, jak 'CGContextAddArcToPoint()' prace, [to] (http : //stackoverflow.com/a/18992153/1338292) jest całkiem dobrym wyjaśnieniem. –

11

Jeśli chcesz mieć zaokrąglone narożniki na dowolnym UIView (lub podklasie), prostym sposobem jest ustawienie właściwości cornerRadius na warstwie widoku. Zobacz Preview rounded image in iphone

+4

Jest to zdecydowanie najłatwiejsze. view.layer.cornerRadius = 10.0f. Upewnij się, że importujesz strukturę Quartz. –

123

Zamiast tworzyć własne ścieżki z linii i łuków, można użyć

[UIBezierPath bezierPathWithRoundedRect:cornerRadius:] 

lub

[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:] 

(druga pozwala określić, które rogi są zaokrąglone)

Dostępne w systemie iOS 3.2 lub nowszym.

+7

Nie zapomnij poprawnie wstawić prostokąta podczas gładzenia, nawet jeśli szerokość linii jest tylko jeden piksel: 'CGRectInform (rect, lineWidth, lineWidth)' – pottedmeat

+20

Dla kompletności pomocne jest również pokazanie, co robisz z tym: ' '' objc [[UIColor lightGrayColor] setFill]; // ustaw kolor bg w kolorze prostokąta UIBezierPath * roundedRect = [UIBezierPath bezierPathWithRoundedRect: _yourDrawingFrame cornerRadius: 4]; [roundedRect fillWithBlendMode: kCGBlendModeNormal alpha: 1.0f]; '' ' – horseshoe7

+9

Właściwie podczas głaskania uważam, że rect powinien być wstawiony tylko o połowę szerokości linii, tzn.' CGRectInset (rect, lineWidth/2.0, lineWidth/2.0) '. Dzieje się tak dlatego, że "narysowana linia jest wyśrodkowana na ścieżce z bokami równoległymi do segmentu ścieżki" (por. '- [UIBezierPath strokeWithBlendMode: alpha:]') – Taum

22

Oto funkcja, którą napisałem, która zaokrągla prostokąt wejściowy za pomocą promienia narożnika.

CGMutablePathRef createRoundedCornerPath(CGRect rect, CGFloat cornerRadius) { 

    // create a mutable path 
    CGMutablePathRef path = CGPathCreateMutable(); 

    // get the 4 corners of the rect 
    CGPoint topLeft = CGPointMake(rect.origin.x, rect.origin.y); 
    CGPoint topRight = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y); 
    CGPoint bottomRight = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); 
    CGPoint bottomLeft = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height); 

    // move to top left 
    CGPathMoveToPoint(path, NULL, topLeft.x + cornerRadius, topLeft.y); 

    // add top line 
    CGPathAddLineToPoint(path, NULL, topRight.x - cornerRadius, topRight.y); 

    // add top right curve 
    CGPathAddQuadCurveToPoint(path, NULL, topRight.x, topRight.y, topRight.x, topRight.y + cornerRadius); 

    // add right line 
    CGPathAddLineToPoint(path, NULL, bottomRight.x, bottomRight.y - cornerRadius); 

    // add bottom right curve 
    CGPathAddQuadCurveToPoint(path, NULL, bottomRight.x, bottomRight.y, bottomRight.x - cornerRadius, bottomRight.y); 

    // add bottom line 
    CGPathAddLineToPoint(path, NULL, bottomLeft.x + cornerRadius, bottomLeft.y); 

    // add bottom left curve 
    CGPathAddQuadCurveToPoint(path, NULL, bottomLeft.x, bottomLeft.y, bottomLeft.x, bottomLeft.y - cornerRadius); 

    // add left line 
    CGPathAddLineToPoint(path, NULL, topLeft.x, topLeft.y + cornerRadius); 

    // add top left curve 
    CGPathAddQuadCurveToPoint(path, NULL, topLeft.x, topLeft.y, topLeft.x + cornerRadius, topLeft.y); 

    // return the path 
    return path; 
} 

Jak korzystać z funkcji, zakładając, że podklasy UIView i zastąpić drawRect:

- (void)drawRect:(CGRect)rect { 

    // constants 
    const CGFloat outlineStrokeWidth = 20.0f; 
    const CGFloat outlineCornerRadius = 15.0f; 

    const CGColorRef whiteColor = [[UIColor whiteColor] CGColor]; 
    const CGColorRef redColor = [[UIColor redColor] CGColor]; 

    // get the context 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // set the background color to white 
    CGContextSetFillColorWithColor(context, whiteColor); 
    CGContextFillRect(context, rect); 

    // inset the rect because half of the stroke applied to this path will be on the outside 
    CGRect insetRect = CGRectInset(rect, outlineStrokeWidth/2.0f, outlineStrokeWidth/2.0f); 

    // get our rounded rect as a path 
    CGMutablePathRef path = createRoundedCornerPath(insetRect, outlineCornerRadius); 

    // add the path to the context 
    CGContextAddPath(context, path); 

    // set the stroke params 
    CGContextSetStrokeColorWithColor(context, redColor); 
    CGContextSetLineWidth(context, outlineStrokeWidth); 

    // draw the path 
    CGContextDrawPath(context, kCGPathStroke); 

    // release the path 
    CGPathRelease(path); 
} 

Przykâadowa:

enter image description here

+0

, ale dlaczego nie używać wbudowanych funkcji ?????????? – Fattie

+0

Śmiało i używaj wbudowanych funkcji. Zrobiłem to tylko dla celów edukacyjnych. –

+0

To nie działa: CGMutablePathRef ścieżka = createRoundedCornerPath (insetRect, outlineCornerRadius); – lespommes

41
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0]; 
CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor); 
[bezierPath stroke]; 
9

CGPathCreateWithRoundedRect() będą robić to, co chcesz.

CGPathRef CGPathCreateWithRoundedRect(
    CGRect rect, 
    CGFloat cornerWidth, 
    CGFloat cornerHeight, 
    const CGAffineTransform *transform 
); 

już w iOS 7.0

+3

Jestem prawie pewien, że to NIE DAJE Wam nowych zaokrąglonych naroży iOS7. Użyj BezierPathWithRoundedRect dla nowych zaokrąglonych narożników iOS7 ... – Fattie

+0

@JoeBlow Nie wiesz, co masz na myśli, funkcja ta została dodana tylko w systemie iOS7 i zapewnia zaokrąglone rogi; czy są jeszcze inne zaokrąglone rogi? –

+0

http://www.mani.de/backstage/?p=483 – Fattie

1

... Może trzy? lata późno, ale obecnie używam tego bez problemów.

@import CoreGraphics; 

@interface YourViewController() 
@property (weak, nonatomic) IBOutlet UIButton *theButton; 
@end 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.theButton.layer.cornerRadius = 5.0f; 
    self.theButton.layer.masksToBounds = YES; 

    // Another useful ones 
    // Scaling the view (width, height) 
    self.theButton.transform = CGAfflineTransformMakeScale(1.50f, 1.50f); 

    // Setting an alpha value (transparency) - nice with Activity Indicator subviews 
    self.theButton.alpha  = 0.8f; 
} 
4

Swift:

let rect: CGRect = ... 

    let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0) 
    CGContextAddPath(context, path.CGPath) 
    CGContextSetStrokeColorWithColor(context, UIColor.clearColor().CGColor) 
    CGContextDrawPath(context, CGPathDrawingMode.FillStroke) 
Powiązane problemy