Create hole in UIView

Hole

See following UI.
Hole

Touch me! is UIButton in ViewController
I added UIView which is same size of UIViewController.
This UIView is set blue color as background.
In this case, UIButton may not be visible.
We sometimes want to add instruction but, don’t expect to touch button.
In that case, this is useful.

How to make hole

Use UIRectFill to realize.
Example

HoleView.h

#import <UIKit/UIKit.h>
@interface HoleInViewController : UIViewController
@end

HoleView.m

#import "HoleView.h"

@implementation HoleView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGRect hole = CGRectMake(100, 100, 100, 40);
    [[UIColor clearColor] setFill];
    UIRectFill(hole);
    
    // This doesn't work
    //CGContextRef context = UIGraphicsGetCurrentContext();
    //CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
    //CGContextFillEllipseInRect( context, hole );
}

How to use(HoleInViewController.m)

#import "HoleInViewController.h"
#import "HoleView.h"

@interface HoleInViewController ()

@property (nonatomic)UIButton *button;
@property (nonatomic)HoleView *holeView;

@end

@implementation HoleInViewController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.button = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.button setTitle:@"Touch me!" forState:UIControlStateNormal];
    [self.button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.holeView = [[HoleView alloc] init];
    self.holeView.backgroundColor = [UIColor colorWithRed:0.0 green:0.1 blue:1.0 alpha:0.3];
    
    [self.view addSubview:self.button];
    [self.view addSubview:self.holeView];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)viewWillLayoutSubviews {
    
    self.button.frame = CGRectMake(100, 100, 100, 40);
    self.holeView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
@end

Circle?

Use kCGBlendModeCopy mode as Blend Mode.

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGRect hole = CGRectMake(100, 100, 100, 40);
    //UIRectFill(hole);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
    CGContextFillEllipseInRect( context, hole );
}

Result

Circle Hole