Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Category on UIButton to clip background image to background before setting it
//
// UIView+ClipBackgroundImageToBounds.m
//
// Created by Barry Allard on 2013-06-18.
// Copyright (c) 2013 Stealth Mode Industries LLC. All rights reserved.
//
// Based on http://stackoverflow.com/questions/262156/uiimage-rounded-corners
//
// MIT License
#import "UIButton+ClipBackgroundImageToBounds.h"
@implementation UIButton (ClipBackgroundImageToBounds)
- (void)setBackgroundImageClippedToBounds:(UIImage *)image forState:(UIControlState)state
{
if (!( ! self.clipsToBounds && self.layer.cornerRadius != 0.0f )) {
// Nothing special to do
[self setBackgroundImage:image forState:state];
return;
}
// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 1.0);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:self.bounds
cornerRadius:self.layer.cornerRadius] addClip];
// Draw your image
[image drawInRect:self.bounds];
// Get the image, here setting the UIImageView image
UIImage* clippedBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
// Lets forget about that we were drawing
UIGraphicsEndImageContext();
// Do what we came here to do
[self setBackgroundImage:clippedBackgroundImage forState:state];
}
@end
//
// UIView+ClipBackgroundImageToBounds.h
//
// Created by Barry Allard on 2013-06-18.
// Copyright (c) 2013 Stealth Mode Industries LLC. All rights reserved.
//
// Based on http://stackoverflow.com/questions/262156/uiimage-rounded-corners
//
// MIT License
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface UIButton (ClipBackgroundImageToBounds)
- (void)setBackgroundImageClippedToBounds:(UIImage *)image forState:(UIControlState)state;
@end
@steakknife

This comment has been minimized.

Show comment Hide comment
@steakknife

steakknife Jun 18, 2013

This probably should be refactored as a category on UIView, and then one category for each control.

Owner

steakknife commented Jun 18, 2013

This probably should be refactored as a category on UIView, and then one category for each control.

@cyborgthefirst

This comment has been minimized.

Show comment Hide comment
@cyborgthefirst

cyborgthefirst Mar 5, 2018

Swift 4 implementation

extension UIButton {
    
    func setBackgroundImageClippedToBounds(_ image: UIImage, for state: UIControlState) {
        if !(!clipsToBounds && layer.cornerRadius != 0.0) {
            setBackgroundImage(image, for: state)
            return
        }
        
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0)
        
        UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).addClip()
        image.draw(in: bounds)
        let clippedBackgroundImage = UIGraphicsGetImageFromCurrentImageContext()
        
        UIGraphicsEndImageContext()
        
        setBackgroundImage(clippedBackgroundImage, for: state)
    }
}

cyborgthefirst commented Mar 5, 2018

Swift 4 implementation

extension UIButton {
    
    func setBackgroundImageClippedToBounds(_ image: UIImage, for state: UIControlState) {
        if !(!clipsToBounds && layer.cornerRadius != 0.0) {
            setBackgroundImage(image, for: state)
            return
        }
        
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0)
        
        UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).addClip()
        image.draw(in: bounds)
        let clippedBackgroundImage = UIGraphicsGetImageFromCurrentImageContext()
        
        UIGraphicsEndImageContext()
        
        setBackgroundImage(clippedBackgroundImage, for: state)
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment