Search code examples
iosiphoneobjective-cuibezierpathobjective-c-category

Creating a UIBezierPath in UIView Category. not being shown


I am trying to create a triangle using UIBezierPath in a category of UIView. but the triangle is not being shown. also getting an : CGContextSetFillColorWithColor. So my question is how to make triangle or any path using a category of UIView. Demo Project

#import "UIView+Bubble.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (Bubble)

+(UIView *)makeBubble{
    UIView *customView = [[UIView alloc] init];
    customView.frame=CGRectMake(0, 0, 320, 500);
    UIBezierPath *triangle = [UIBezierPath bezierPath];
    [triangle moveToPoint:CGPointMake(100, 0)];
    [triangle addLineToPoint:CGPointMake(0, 100)];
    [triangle addLineToPoint:CGPointMake(200, 100)];
    [triangle closePath];
    [[UIColor blackColor] setFill];
    [triangle fill];
    customView.layer.shadowPath = [triangle CGPath];
    return customView;
}
@end

In ViewController.m using it like:-

- (void)viewDidLoad
{
    UIView *helpBubble=[UIView makeBubble];
    [self.view addSubview:helpBubble];
}

Solution

  • In your UIView+Bubble.h category UIBezierPath tries to draw triangle on a null context. If you want to draw shape using UIBezierPath like above, you have to put this code inside drawRectmethod of a View class.

    On the other hand, you could create a new context to draw. You may modify your makeBubble method as follow:

    +(UIView *)makeBubble{
       // declare UIimageView, not UIView
       UIImageView *customView = [[UIImageView alloc] init];
       customView.frame=CGRectMake(0, 0, 320, 500);
    
       // create a new contex to draw
       UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0);
    
       UIBezierPath *triangle = [UIBezierPath bezierPath];
       [triangle moveToPoint:CGPointMake(100, 0)];
       [triangle addLineToPoint:CGPointMake(0, 100)];
       [triangle addLineToPoint:CGPointMake(200, 100)];
       [triangle closePath];
       [[UIColor blackColor] setFill];
       [triangle fill];
    
       customView.image = UIGraphicsGetImageFromCurrentImageContext();
    
       UIGraphicsEndImageContext();
    
       return customView;
    }
    



    EDIT:

    to make it dynamic you could pass a cgRect argument, like

    +(UIView *)makeBubble:(CGRect)rect
    

    also change to customView.frame=rect; and UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0); inside this method. And call makeBubble:(CGRect)rect method as

    UIView *helpBubble=[UIView makeBubble:/*your desire rect*/];
    

    P.S. it will be great if you calculate the points depending on the rect too.