set cornerRadius and setbackgroundimage to UIButton - ios

I am trying to set cornerRadius of UIButton but I dont know how to do it.
If I do like this:
button.layer.cornerRadius = 5;
works well, if I do like this :
button.layer.cornerRadius = 5;
[button setBackgroundColor:[UIColor colorWithPatternImage:radialGradient]];
the corners are not rounded.
I know I could solve this whit
[button.layer setMasksToBounds:YES];
but I specifically looking for different solution, because I add some arrows to the button and if I set mask to bounds the arrow are masked.
EDIT :
radialGradient is made whit func
+ (UIImage *)getRadialGradientImage:(CGSize)size centre:(CGPoint)centre radius:(float)radius startColor:(UIColor *)startColor endColor:(UIColor *)endColor{
// Initialise
UIGraphicsBeginImageContextWithOptions(size, YES, 1);
// Create the gradient's colours
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
const CGFloat *component_first = CGColorGetComponents([startColor CGColor]);
CGFloat red1 = component_first[0];
CGFloat green1 = component_first[1];
CGFloat blue1 = component_first[2];
const CGFloat *component_second = CGColorGetComponents([endColor CGColor]);
CGFloat red2 = component_second[0];
CGFloat green2 = component_second[1];
CGFloat blue2 = component_second[2];
const CGFloat components[8] = { red1,green1,blue1,1,red2,green2,blue2,1}; // End color
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
CGGradientRef myGradient = CGGradientCreateWithColorComponents (myColorspace, components, locations, num_locations);
// Normalise the 0-1 ranged inputs to the width of the image
CGPoint myCentrePoint = CGPointMake(centre.x * size.width, centre.y * size.height);
float myRadius = MIN(size.width, size.height) * radius;
// Draw it!
CGContextDrawRadialGradient (UIGraphicsGetCurrentContext(), myGradient, myCentrePoint,
0, myCentrePoint, myRadius,
kCGGradientDrawsAfterEndLocation);
// Grab it as an autoreleased image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// Clean up
CGColorSpaceRelease(myColorspace); // Necessary?
CGGradientRelease(myGradient); // Necessary?
UIGraphicsEndImageContext(); // Clean up
return image;
}

Here is how I would create a button through code and set its background color.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 100,50);
[btn setTitle:#"Hello" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:128.0/255.0f green:0.0/255.0f blue:0.0/255.0f alpha:0.7]];
btn.frame = CGRectMake(100.0, 100.0, 120.0, 50.0);//width and height should be same value
btn.clipsToBounds = YES;
btn.layer.cornerRadius = 20;//half of the width
btn.layer.borderColor=[UIColor redColor].CGColor;
btn.layer.borderWidth=2.0f;
[self.view addSubview:btn];
Below is the image of the button that is related with the above code
You can always play around with code and create the colors that you need for background and border. Hope this would help you out.

btn.clipsToBounds = YES;
i Just added this and it worked for me. I was actually able to set corner radius to UIButton with setting an image to that particular UIButton.

If you are using the image in your button background then you need to set clipsTobounds to true.
button.layer.cornerRadius = 10
button.clipsToBounds = true

You can also have:
btn.clipsToBounds = true;

//create button like this
UIButton *cancel=[[UIButton alloc]initWithFrame:CGRectMake(9, 9,35,35)];
cancel.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"BackX.png"]];
[cancel setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[cancel.layer setBorderColor: [[UIColor blackColor] CGColor]];
[cancel.layer setBorderWidth: 1.0];
cancel.contentMode=UIViewContentModeScaleAspectFill;
cancel.clipsToBounds=YES;
cancel.layer.cornerRadius=8.0;
[cancel addTarget:self action:#selector(cancelbtnclk1:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:cancel];
Before that add QuartzCore Framework and import QuartzCore/CoreAnimation.h in your .h file.
hope it will helps you..

Using UIGraphicsImageRenderer, you can use the cgContext property of UIGraphicsImageRendererContext to access the CGContext and add a rounded path:
UIGraphicsImageRenderer(size: size).image { context in
let rect = CGRect(origin: .zero, size: size)
let clipPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
context.cgContext.addPath(clipPath)
context.cgContext.setFillColor(self.cgColor)
context.cgContext.fillPath()
}
Added as an extension to UIColor:
extension UIColor {
public func image(_ size: CGSize = CGSize(width: 10, height: 10), cornerRadius: CGFloat = 4) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { context in
let rect = CGRect(origin: .zero, size: size)
let clipPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
context.cgContext.addPath(clipPath)
context.cgContext.setFillColor(self.cgColor)
context.cgContext.fillPath()
}
}
}
This approach will also allow you to add a shadow to the button unlike using clipsToBounds.

Set corner Radius in Identity Inspector for Button. See Pic
Set Background image in Attribute Inspector for Button. See pic

Related

How to add subview out of the parent view bounds

I have a view with bezier path mask layer. Now I need to add to my view a subview, that has to be placed outside of the superView
class MiddleSegmentView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
createMaskView()
}
func createPath() -> UIBezierPath {
let width = self.frame.size.width
let height = self.frame.size.height
let lineWidth = -height/tan(angle)
let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 0.0, y: 0.0))
path.addLineToPoint(CGPoint(x: width, y: 0))
path.addLineToPoint(CGPoint(x: width - lineWidth, y: height))
path.addLineToPoint(CGPoint(x: lineWidth, y: height))
path.addLineToPoint(CGPoint(x: 0.0, y: 0.0))
path.closePath()
return path
}
func createMaskView() {
let mask = CAShapeLayer()
mask.path = createPath().CGPath
self.layer.mask = mask
}
//Creating shadow
override func drawRect(rect: CGRect) {
super.drawRect(rect)
//createShadow()
let shadowView = SegmentShadow(frame: CGRect(x: 0, y: 0, width: 10, height: 40))
self.clipsToBounds = false
self.addSubview(shadowView)
shadowView.bringToFront()
}
}
Although my view is generating correctly my shadowView is being cropped by superView bounds. How can I avoid such behaviour?
There are a couple of ways to achieve what you want:
METHOD ONE: INSERT SHADOW SHAPE INTO EACH TAB
Create the tabs you want and then add a custom CAShapeLayer to each one:
//insert a CAShapeLayer into each 'tab'
CAShapeLayer * shadowLayer = [self trapezium];
shadowLayer.fillColor = grey.CGColor;
shadowLayer.shadowOpacity = 1.0f;
shadowLayer.shadowRadius = 1.0f;
shadowLayer.shadowOffset = CGSizeZero;
shadowLayer.shadowColor = [UIColor blackColor].CGColor;
[tab.layer insertSublayer:shadowLayer atIndex:0];
You can access the tabs and shadowLayer like this (given an array 'tabs'):
//then access like this
UIView * tab = tabs[2];
[self.view bringSubviewToFront:tab];
CAShapeLayer * layer = (CAShapeLayer*)tab.layer.sublayers[0];
layer.fillColor = orange.CGColor;
METHOD TWO: MOVE SHADOW VIEW
Another way is to create a single custom 'tabShadowView' and simply move that to the location of the selected tab. Here's the code for laying out the tabs in a custom view:
grey = [_peacock colourForHex:#"#ACA499" andAlpha:1.0f];
orange = [_peacock colourForHex:#"#CB9652" andAlpha:1.0f];
tabShadowView = [UIView new];
tabShadowView.frame = CGRectMake(0, 20, 100, 40);
tabShadowView.layer.shadowPath = [self trapezium].path;
tabShadowView.layer.shadowColor = [UIColor blackColor].CGColor;
tabShadowView.layer.shadowOffset = CGSizeZero;
tabShadowView.layer.shadowRadius = 1.0f;
tabShadowView.layer.shadowOpacity = 0.5f;
[self.view addSubview:tabShadowView];
customTabView = [UIView new];
customTabView.frame = CGRectMake(0, 0, w, 60);
[self.view addSubview:customTabView];
NSArray * titles = #[#"Button A", #"Button B", #"Button C",#"Button D"];
tabs = [NSMutableArray new];
float xOff = 0.0f;
for (NSString * title in titles){
UIView * tab = [UIView new];
tab.frame = CGRectMake(xOff, 20, 100, 40);
tab.backgroundColor = grey;
tab.layer.mask = [self trapezium];
[customTabView addSubview:tab];
[tabs addObject:tab];
UIButton * button = [UIButton new];
button.frame = tab.bounds;
[button setTitle:title forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.font = [UIFont systemFontOfSize:14.0f weight:UIFontWeightRegular];
[button addTarget:self action:#selector(tabSelected:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:[titles indexOfObject:title]];
[tab addSubview:button];
xOff += 70.0f;
}
[self updateTabsForSelected:tabs[1]];
Put the above code in the place you layout your views. The tabShadowView is the view that we move about, it's right at the bottom of the view hierarchy. Then the for loop just adds tabs in on top of it. Here are the methods that it uses:
-(void)tabSelected:(UIButton *)button {
UIView * tab = tabs[(int)button.tag];
[self updateTabsForSelected:tab];
}
-(void)updateTabsForSelected:(UIView *)tab{
for (UIView * view in customTabView.subviews){
[customTabView sendSubviewToBack:view];
view.backgroundColor = grey;
}
[customTabView bringSubviewToFront:tab];
tab.backgroundColor = orange;
tabShadowView.transform = CGAffineTransformMakeTranslation([tabs indexOfObject:tab]*70, 0);
}
-(CAShapeLayer *)trapezium {
UIBezierPath * path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointZero];
[path addLineToPoint:CGPointMake(20, 40)];
[path addLineToPoint:CGPointMake(80, 40)];
[path addLineToPoint:CGPointMake(100, 0)];
[path closePath];
CAShapeLayer * layer = [CAShapeLayer layer];
layer.path = path.CGPath;
return layer;
}
Tapping on a button then moves the shadow under the selected tab. The code is quick and dirty, you'll need to add more logic, clean up etc, but you get the point, method one inserts a shadow view into each, method two moves a single shadow view about underneath the tabs.

How do a set an opaque 1px high shadow image for a UINavigationBar?

In my application delegate's didFinishLaunchingWithOptions function, I try to customize the appearance of my navigation bar.
[UINavigationBar appearance].translucent = NO;
[[UINavigationBar appearance]
setBackgroundImage:[UIImage
imageWithColor:[UIColor whiteColor]
size:CGSizeMake(1.0f, 1.0f)
]
forBarMetrics:UIBarMetricsDefault
];
[UINavigationBar appearance].shadowImage = [UIImage
imageWithColor:[UIColor redColor]
size:CGSizeMake(0.5f, 0.5f)
];
I expect a 1px tall opaque red shadow. Instead I am given a 2px tall translucent red shadow. How can make it appear exactly as I want it to? I've done the analogous appearance settings to UITabBar. It, on the other hand, behaves nicely.
The category function that creates dynamic images is defined as so:
+ (UIImage*)imageWithColor:(UIColor *)color size:(CGSize)size
{
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
You need to create a graphics context that is retina-aware :
let pixelScale = UIGraphicsBeginImageContextWithOptions(fillRect.size, false, UIScreen.main.scale)
After that, your shadow image will become 1 physical pixel tall.
Here's full code:
extension UIImage {
static func imageWithColor(color: UIColor) -> UIImage {
let pixelScale = UIScreen.main.scale
let pixelSize = 1 / pixelScale
let fillSize = CGSize(width: pixelSize, height: pixelSize)
let fillRect = CGRect(origin: CGPoint.zero, size: fillSize)
UIGraphicsBeginImageContextWithOptions(fillRect.size, false, pixelScale)
let graphicsContext = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(graphicsContext, color.CGColor)
CGContextFillRect(graphicsContext, fillRect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
On GitHub:
https://github.com/salutis/swift-image-with-color
Uh...is this what you want?
In my view controller, I simply added a UIView with 1 pixel height and an offset of 44pixels:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
[self setupNavBar];
}
-(void)setupNavBar
{
self.navigationItem.title = #"Contacts";
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIView *bar = [[UIView alloc] initWithFrame:CGRectMake(0, 44, applicationFrame.size.width, 1.0)];
bar.backgroundColor = [UIColor redColor];
[self.navigationController.navigationBar addSubview:bar];
}
You can change the color to whatever you want.

adding 'click' effect on UIButton

i have a UIButton that when I tap it, goes down giving effect of a click/tap.
My problem is that I have to add a black border around UIButton, but adding this keeps border static and it doesn't move down with the UIButton, the code that let me have click effect on UIButton is this:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGSize size = self.bounds.size;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect faceRect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContextWithOptions(faceRect.size, NO, 0.0);
[[self faceColorForState:self.state] set];
[self drawRoundedRect:faceRect radius:self.radius context:UIGraphicsGetCurrentContext()];
UIImage *faceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[self sideColorForState:self.state] set];
CGRect sideRect = CGRectMake(0, size.height * 1.0 / 4.0, size.width, size.height * 3.0 / 4.0);
[self drawRoundedRect:sideRect radius:self.radius context:context];
CGRect faceShrinkedRect;
if(self.state == UIControlStateSelected || self.state == UIControlStateHighlighted) {
faceShrinkedRect = CGRectMake(0, self.depth, size.width, size.height - self.margin);
} else {
faceShrinkedRect = CGRectMake(0, 0, size.width, size.height - self.margin);
}
[faceImage drawInRect:faceShrinkedRect];
}
You're overcomplicating things using drawRect:. The easiest way to do this is to create 2 images for the background of your button, one with a black border. Then use:
[myButton setBackgroundImage:[UIImage imageNamed:<up-image>] forState:UIControlStateNormal];
[myButton setBackgroundImage:[UIImage imageNamed:<down-image>] forState:UIControlStateHighlighted];
You could re-use your code to create the images in code if necessary.
Maybe a category method on UIImage say:
+(UIImage *)buttonBackgroundImageWithColor:(UIColor *) color highlighted: (BOOL) highlighted

How do you change UIButton image alpha on disabled state?

I have a UIButton with an image and on its disabled state, this image should have .3 alpha.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *arrowImage = [UIImage imageNamed:#"arrow.png"];
[button setImage:arrowImage forState:UIControlStateNormal];
// The arrow should be half transparent here
[button setImage:arrowImage forState:UIControlStateDisabled];
How do I accomplish this?
UPDATE: I noticed, by default UIButton does reduce the alpha of the image on disabled state (probably at .5?). But I'd like to know how to fine-tune this value.
If setting alpha while the button is disabled doesn't work, then just make your disabled image at the alpha value you desire.
Just tested this, you can set the alpha on the UIButton, regardless of state and it works just fine.
self.yourButton.alpha = 0.25;
Credit goes to #bryanmac for his helpful answer. I used his code as a starting point, but found the same thing can be achieved without using a UIImageView.
Here's my solution:
- (UIImage *)translucentImageFromImage:(UIImage *)image withAlpha:(CGFloat)alpha
{
CGRect rect = CGRectZero;
rect.size = image.size;
UIGraphicsBeginImageContext(image.size);
[image drawInRect:rect blendMode:kCGBlendModeScreen alpha:alpha];
UIImage * translucentImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return translucentImage;
}
Set the button's background image for disabled state:
UIImage * disabledBgImage = [self translucentImageFromImage:originalBgImage withAlpha:0.5f];
[button setBackgroundImage:disabledBgImage forState:UIControlStateDisabled];
EDIT:
I refined my solution further by creating a category on UIImage with this method:
- (UIImage *)translucentImageWithAlpha:(CGFloat)alpha
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
[self drawInRect:bounds blendMode:kCGBlendModeScreen alpha:alpha];
UIImage * translucentImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return translucentImage;
}
Set the button's background image for disabled state:
UIImage * disabledBgImage = [originalBgImage translucentImageWithAlpha:0.5f];
[button setBackgroundImage:disabledBgImage forState:UIControlStateDisabled];
You need two instances of UIImage, one for enabled and one for disabled.
The tough part is for the disabled one, you can't set alpha on UIImage. You need to set it on UIImageView but button doesn't take an UIImageView, it takes a UIImage.
If you really want to do this, you can load the same image into the disabled button state after creating a resultant image from the UIImageView that has the alpha set on it.
UIImageView *uiv = [UIImageView alloc] initWithImage:[UIImage imageNamed:#"arrow.png"];
// get resultant UIImage from UIImageView
UIGraphicsBeginImageContext(uiv.image.size);
CGRect rect = CGRectMake(0, 0, uiv.image.size.width, uiv.image.size.height);
[uiv.image drawInRect:rect blendMode:kCGBlendModeScreen alpha:0.2];
UIImage *disabledArrow = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[button setImage:disabledArrow forState:UIControlStateDisabled];
That's a lot to go through to get an alpha controlled button image. There might be an easier way but that's all I could find. Hope that helps.
Subclassing UIButton and extending the setEnabled: method seems to work:
- (void) setEnabled:(BOOL)enabled {
[super setEnabled:enabled];
if (enabled) {
self.imageView.alpha = 1;
} else {
self.imageView.alpha = .25;
}
}
I haven't tested it thoroughly, but did find the value resets if the screen is rotated. Adding the same code to the setFrame: method fixes that, but I'm not sure if there are other situations where this value is changed.
In case anyone needs it, here's an answer in Swift:
Subclass UIButton and override enabled
class MyCustomButton: UIButton {
override var enabled: Bool {
didSet{
alpha = enabled ? 1.0 : 0.3
}
}
Set the class of any button you want to have this property to "MyCustomButton" (or whatever you choose to name it)
#IBOutlet weak var nextButton: MyCustomButton!
I found that none of these solutions really work. The cleanest way of doing it is to subclass, and instead of using self.imageView, just add your own custom imageView like this:
_customImageView = [[UIImageview alloc] initWithImage:image];
Then add your custom alpha like so:
- (void)setEnabled:(BOOL)enabled {
[super setEnabled:enabled];
if (enabled) {
_customImageView.alpha = 1.0f;
} else {
_customImageView.alpha = 0.25f;
}
}
Swift 3:
extension UIImage {
func copy(alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: CGPoint.zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Usage:
button.setImage(image.copy(alpha: 0.3), for: .disabled)
The button’s image view. (read-only)
#property(nonatomic, readonly, retain) UIImageView *imageView
Although this property is read-only, its own properties are read/write.
A swift 4 version of Steph Sharp's answer:
extension UIImage {
func translucentImageWithAlpha(alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0)
let bounds = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.draw(in: bounds, blendMode: .screen, alpha: alpha)
let translucentImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return translucentImage!
}
}
Which you can use like this:
if let image = self.image(for: .normal) {
self.setImage(image.translucentImageWithAlpha(alpha: 0.3), for: .disabled)
}
- (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image; }
Use: [btnRegister setBackgroundImage:[self imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled];
btnRegister.enabled = false;
Here's a solution that extends the UIButton class. No need to sub-class. In my example, button alpha is set to 0.55 if .isEnabled is false, and 1.0 if it's true.
Swift 5:
extension UIButton {
override open var isEnabled: Bool {
didSet {
self.alpha = isEnabled ? 1.0 : 0.55
}
}
}

How to crop UIImage on oval shape or circle shape?

Please give ideas for how to crop UIImage on oval shape or circle shape. Please share your ideas.
#import <QuartzCore/QuartzCore.h>
CALayer *imageLayer = YourImageview.layer;
[imageLayer setCornerRadius:5];
[imageLayer setBorderWidth:1];
[imageLayer setMasksToBounds:YES];
by increasing radius it will become more round-able.
As long as the image is a square, you can get a perfect circle by taking half the width as the corner radius:
[imageView.layer setCornerRadius:imageView.frame.size.width/2];
You also need to add
[imageView.layer setMasksToBounds:YES];
Swift 4.2
import QuartzCore
var imageLayer: CALayer? = YourImageview.layer
imageLayer?.cornerRadius = 5
imageLayer?.borderWidth = 1
imageLayer?.masksToBounds = true
I started looking into this a couple of weeks back. I tried all the suggestions here, none of which worked well. In the great tradition of RTFM I went and read Apple's documentation on Quartz 2D Programming and came up with this. Please try it out and let me know how you go.
The code could be fairly easily altered to crop to an elipse, or any other shape defined by a path.
Make sure you include Quartz 2D in your project.
#include <math.h>
+ (UIImage*)circularScaleAndCropImage:(UIImage*)image frame:(CGRect)frame {
// This function returns a newImage, based on image, that has been:
// - scaled to fit in (CGRect) rect
// - and cropped within a circle of radius: rectWidth/2
//Create the bitmap graphics context
UIGraphicsBeginImageContextWithOptions(CGSizeMake(frame.size.width, frame.size.height), NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
//Get the width and heights
CGFloat imageWidth = image.size.width;
CGFloat imageHeight = image.size.height;
CGFloat rectWidth = frame.size.width;
CGFloat rectHeight = frame.size.height;
//Calculate the scale factor
CGFloat scaleFactorX = rectWidth/imageWidth;
CGFloat scaleFactorY = rectHeight/imageHeight;
//Calculate the centre of the circle
CGFloat imageCentreX = rectWidth/2;
CGFloat imageCentreY = rectHeight/2;
// Create and CLIP to a CIRCULAR Path
// (This could be replaced with any closed path if you want a different shaped clip)
CGFloat radius = rectWidth/2;
CGContextBeginPath (context);
CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
CGContextClosePath (context);
CGContextClip (context);
//Set the SCALE factor for the graphics context
//All future draw calls will be scaled by this factor
CGContextScaleCTM (context, scaleFactorX, scaleFactorY);
// Draw the IMAGE
CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
[image drawInRect:myRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Include the following code in your UIView class replacing "monk2.png" with your own image name.
- (void)drawRect:(CGRect)rect {
UIImage *originalImage = [UIImage imageNamed:[NSString stringWithFormat:#"monk2.png"]];
CGFloat oImageWidth = originalImage.size.width;
CGFloat oImageHeight = originalImage.size.height;
// Draw the original image at the origin
CGRect oRect = CGRectMake(0, 0, oImageWidth, oImageHeight);
[originalImage drawInRect:oRect];
// Set the newRect to half the size of the original image
CGRect newRect = CGRectMake(0, 0, oImageWidth/2, oImageHeight/2);
UIImage *newImage = [self circularScaleAndCropImage:originalImage frame:newRect];
CGFloat nImageWidth = newImage.size.width;
CGFloat nImageHeight = newImage.size.height;
//Draw the scaled and cropped image
CGRect thisRect = CGRectMake(oImageWidth+10, 0, nImageWidth, nImageHeight);
[newImage drawInRect:thisRect];
}
To have imageView in oval shape is not difficult.
You can do the following
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;
If the rect passed to bezierPathWithOvalInRect is Square the image will be cropped to circle.
Swift Code
let path = UIBezierPath(ovalIn: yourImageView.bounds)
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
yourImageView.layer.mask = maskLayer
To make a RoundShape Image
Step1: in .h file
#property (strong, nonatomic) IBOutlet UIImageView *songImage;
Step2: in .m file
- (void)viewDidLoad
{
self.songImage.layer.cornerRadius = self.songImage.frame.size.width / 2;
self.songImage.clipsToBounds = YES;
//To give the Border and Border color of imageview
self.songImage.layer.borderWidth = 1.0f;
self.songImage.layer.borderColor = [UIColor colorWithRed:249/255.0f green:117/255.0f blue:44/255.0f alpha:1.0f].CGColor;
}
OR For Swift
cell.songImage.layer.cornerRadius = cell.songImage.frame.size.width / 2;
cell.songImage.clipsToBounds = true
//To give the Border and Border color of imageview
cell.songImage.layer.borderWidth = 1.0
cell.songImage.layer.borderColor = UIColor(red: 50.0/255, green: 150.0/255, blue: 65.0/255, alpha: 1.0).CGColor
After a long search I found the correct way to circle the image
Download the Support archive file from URL http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
#import "UIImage+RoundedCorner.h"
#import "UIImage+Resize.h"
Following lines used to resize the image and convert in to round with radius
UIImage *mask = [UIImage imageNamed:#"mask.jpg"];
mask = [mask resizedImage:CGSizeMake(47, 47) interpolationQuality:kCGInterpolationHigh ];
mask = [mask roundedCornerImage:23.5 borderSize:1];
SWIFT
var vwImage = UIImageView(image: UIImage(named: "Btn_PinIt_Normal.png"))
vwImage.frame = CGRectMake(0, 0, 100, 100)
vwImage.layer.cornerRadius = vwImage.frame.size.width/2
If you only need a perfect circle, changing the shape of the UIImageView could help.
Simply add the QuartzCore framework to your project and add these lines of code somewhere in the lifecycle before the imageView is displayed:
#import <QuartzCore/QuartzCore.h>
.
.
.
//to crop your UIImageView to show only a circle
yourImageView.layer.cornerRadius = yourImageView.frame.size.width/2;
yourImageView.clipsToBounds = YES;
Check out CGImageCreateWithMask. Create a mask of your oval shape, then apply it to the image.
you should refer This ...
// Create the image from a png file
UIImage *image = [UIImage imageNamed:#"prgBinary.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Get size of current image
CGSize size = [image size];
// Frame location in view to show original image
[imageView setFrame:CGRectMake(0, 0, size.width, size.height)];
[[self view] addSubview:imageView];
[imageView release];
// Create rectangle that represents a cropped image
// from the middle of the existing image
CGRect rect = CGRectMake(size.width / 4, size.height / 4 ,
(size.width / 2), (size.height / 2)); //oval logic goes here
// Create bitmap image from original image data,
// using rectangle to specify desired crop area
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(0, 200, (size.width / 2), (size.height / 2))];
[[self view] addSubview:imageView];
[imageView release];
SWIFT 3 answer comes from #Mohammad Sadiq
let path = UIBezierPath.init(ovalIn: workingImgaeView.bounds)
let maskLayer = CAShapeLayer(layer: layer)
maskLayer.path = path.cgPath
workingImgaeView.layer.mask = maskLayer
This should work,
Try pasting below code in viewDidLoad().
self.myImage.layer.cornerRadius = self.myImage.frame.size.width / 2;
self.myImage.clipsToBounds = YES;

Resources