How to design fully rounded button in iOS 7? [closed] - iphone

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm creating an application for iOS 7 and i want a fully rounded button like in calling keypad.
Does anyone know how we can make button to be fully rounded for iOS 7, also is it possible to set an image for rounded button ?

Yep, easy. You need to add the quartzcore framework, and the frame for your button must be square, equal width and height.
#import <QuartzCore/QuartzCore.h>
myButton.layer.cornerRadius = myButton.frame.size.height/2.0;
myButton.clipsToBounds = YES;
myButton.layer.borderWidth = 1.0;
myButton.layer.borderColor = [UIColor blueColor].CGColor;
myButton.layer.backgroundColor =[UIColor cyanColor].CGColor;
myButton.backgroundColor = nil;
Edit addition for ALSO setting image..
UIImage *buttonImage = [UIImage imageNamed:foobar];
[myButton setImage:buttonImage forState:UIControlStateNormal];
//May as well ditch the colours set to .layer if you do this
or you could do something like this:
[myButton setImage:[self generateButtonImageOfSize:myButton.frame.size] forState:UIControlStateNormal];
-(UIImage *)generateButtonImageOfSize:(CGSize )buttonSize{
UIGraphicsBeginImageContextWithOptions(buttonSize, NO , 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor);
CGContextSetLineWidth(context, 1.0);
CGRect br = CGRectMake(0, 0, buttonSize.width, buttonSize.height);
CGContextFillEllipseInRect(context, br);
CGContextStrokeEllipseInRect(context, br);
//theres a pretty circle, wanna draw other stuff? do it here..
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}

// imprort framework in .h file
**#import <QuartzCore/QuartzCore.h>**
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"imagename.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(click) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(135.0, 180.0, 40.0, 40.0);//width and height should be same value
button.clipsToBounds = YES;
button.layer.cornerRadius = 20;//half of the width
button.layer.borderColor=[UIColor redColor].CGColor;
button.layer.borderWidth=2.0f;
[self.view addSubview:button];

for that you need to use QuartzCore/QuartzCore framework . a good tutorial here look at this round button example

There are few ways. For example you may use UIImageView for button image and round corners for it
UIImageView *avatar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 33, 33)];
avatar.contentMode = UIViewContentModeScaleAspectFill;
avatar.layer.cornerRadius = 16;
avatar.layer.borderColor = [UIColor whiteColor].CGColor;
avatar.layer.borderWidth = 1;
avatar.clipsToBounds = YES;

Related

How to set the background color of an UIButtonTypeRoundedRect Button?

I tried tintColor = [UIColor redColor] and it does the job, but it only show the expected color when the button is being pressed.
In Coloration of UIButtons of type UIButtonTypeRoundedRect they answer the same question but you need an image to implement it, is there any way to do it without an image?
Here is what i want: image
Here is what i'm getting using images: image
Remember... NO IMAGES!
well using an image is one way of doing it, but i guess you already clear that in your question that you do not wish to use an image. here is button that i created and colored programmatically.
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];
you can change the [UIColor ColorWithRed: wo whatever you want or even use [UIColor redColor] or any other things you want to do with this.
here is a screen shot:
adding a background color to rounded button is not possible, change the type of the button to custom and then use quartz core to set a round button. so add that to your project and import it in the .m and it should work. hope this works for you man.
to change the button to something similar to the image you showed change the frame to :
btn.frame = CGRectMake(50.0, 100.0, 200.0, 50.0);
and change the radius to :
btn.layer.cornerRadius = 7;
that should do it.
You can create a method to generate an UIImage from a UIColor and then set the returned image as the background of the button, for example:
- (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
UIImage *image = [self imageWithColor:[UIColor colorWithRed:151.0/255.0
green:36.0/255.0
blue:40.0/255.0
alpha:1.0]];
[self.button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.button setBackgroundImage:image forState:UIControlStateNormal];
self.button.layer.cornerRadius = 6.0;
self.button.layer.borderWidth = 1.0;
self.button.layer.borderColor = [UIColor darkGrayColor].CGColor;
self.button.clipsToBounds = YES;
Using this I get
here's how I should do it:
download a button image from the internet or create an image yourself, to make it look like you want it to look like. Photoshop might be your best shot for this. make sure you have a transparent background and save it as a .png.
then add it to your xcode project. to make the button:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundImage:[UIImage imageNamed:#"yourImage.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(buttonAction)
forControlEvents:UIControlEventTouchDown];
[btn setTitle:#"Use it!" forState:UIControlStateNormal];
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
btn.titleLabel.font = [UIFont systemFontOfSize:20];
btn.frame = CGRectMake(position and size of your button);
[self.view addSubview:btn];
yourImage.png needs to be replaced with the name of your image.
The buttonAction is the action your button performs when it's tapped. if you just add:
- (void) buttonAction
{
}
anywhere in your file, anything you added between those brackets will be performed.
Make sure the size of your button is the same as the size of your CGRect, to make sure it doesn't look stretched out or anything you don't want it to look like.
If you have any questions, feel free to ask them.
Hope this helped you

UINavigationBar with two rounded corners

I have seen this answer
https://stackoverflow.com/a/9243472/563381
And while it works well visual as soon as you set the mask on the Navigation bar's layer it no longer responds to touches... So the back button that appears on the bar can't be clicked. Any solution to cause touches to go through a CALAyer? I didnt think CALayer's blocked touches or that a mask would ever block touches.
Well, I really don't know why CALayer blocks touches and this sounds odd to me...
The way I round corners of UINavigationBar consists in putting 2 UIImageView (10x10 pixels) in the corners and add 2 images to them. These images work as a mask, without blocking touches. If you use antialiasing to draw your images, the look is perfect.
You should try to use this code:
self.navigationController.navigationBar.translucent = YES;
This wil turn on your back button.You can see your button, but its in another layer. That's why it will not work the touches..
UPDATE:
Use this line of code for test. This will work like a charm for you.
//Style UINavigationBar
UIView *background = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
background.backgroundColor = [UIColor blackColor];
[self.view addSubview:background];
self.navigationController.navigationBar.tintColor = [UIColor cyanColor];
self.navigationController.navigationBar.translucent = YES;
CALayer *capa = [self.navigationController navigationBar].layer;
[capa setShadowColor: [[UIColor blackColor] CGColor]];
[capa setShadowOpacity:0.85f];
[capa setShadowOffset: CGSizeMake(0.0f, 1.5f)];
[capa setShadowRadius:2.0f];
[capa setShouldRasterize:YES];
//Round
CGRect bounds = capa.bounds;
bounds.size.height += 10.0f; //I'm reserving enough room for the shadow
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
[capa addSublayer:maskLayer];
capa.mask = maskLayer;
//Back Btn
UIButton *btnback = [UIButton buttonWithType:UIButtonTypeCustom];
[btnback setFrame:CGRectMake(0, 0, 54, 29)];
[btnback setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
UILabel * btnlabel = [[UILabel alloc]initWithFrame:CGRectMake(15, 0, 40, 23)];
btnlabel.backgroundColor = [UIColor clearColor];
btnlabel.textColor = [UIColor whiteColor];
btnlabel.font = [UIFont boldSystemFontOfSize:13];
btnlabel.text = #"back";
[btnback addSubview:btnlabel];
[btnback addTarget:self action:#selector(backHome:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:btnback];

iphone - Can I draw a UIView instance in drawRect?

I am trying something like below
UIView * view = [UIView new];
view.frame = CGRectMake(50, 50, 200, 200);
view.bounds = CGRectMake(0, 0, 400, 400);
view.backgroundColor = [UIColor grayColor];
UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(50, 50, 300, 50)];
[btn setTitle:#"Button" forState:UIControlStateNormal];
[view addSubview:btn];
CALayer * layer = [view layer];
[layer drawInContext:ctx];
My questions is
1) Like we draw images or text with CGContextRef , can we draw a UIView instance the same way ?
I am not so familliar with the core graphics framework , so please let me know the possibilities . My basic aim is to be able to draw custom views in drawRect using CGContextRef by any means .
Thank you in advance !!!
You have to implement -(void)drawRect:(CGRect)rect method in your subclass of UIView. In this method you should draw to the current context.

Change gradient for UIButton for different states

Recently I've encountered a problem. I have a UIButton and 2 images for it. 1 for normal state and 1 for highlighted. The problem is that normal state image is transparent and I should use gradient to fill it. But if I do it, my highlighted image never appears. Here's the part of the code:
UIImage *balloonImage = [[UIImage imageNamed:#"balloon.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
UIImage *balloonImageDown = [[UIImage imageNamed:#"balloon-down.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, 0, 320 - 45 - 10, 100);
gradient.cornerRadius = 3.0f;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:221.0f/255.0f green:231.0f/255.0f blue:246.0f/255.0f alpha:1.0f]CGColor], (id)[[UIColor colorWithRed:191.0f/255.0f green:207.0f/255.0f blue:234.0f/255.0f alpha:1.0f] CGColor], nil];
self.balloonButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.balloonButton.layer insertSublayer:gradient atIndex:0];
[self.balloonButton setBackgroundImage:balloonImage forState:UIControlStateNormal];
[self.balloonButton setBackgroundImage:balloonImageDown forState:UIControlStateHighlighted];
self.theImageView = [[[UIImageView alloc]init]autorelease];
[self.balloonButton addSubview:theImageView];
[self.contentView addSubview:balloonButton];
The gradient looks as it should and everything is working. Except for changing the image if the button is tapped.
Is there a way to put balloonImageDown in front of the gradient? Or how can I do that?
Any help would be appreciated.
[yourButton setTitleColor:[UIColor colorWithRed:0.3 green:0.6 blue:0.9 alpha:0.5]
// set 'alpha' to something less than 1. -----^^^
This is what you do to make it transparent.(changing the alpha value)
You should be changing these values in touchdown and touch up method.

How to use UIView's contentStretch

I want to use an image of size 27x27 with the center 1 pixel stretchable as the backgroundImage of an UIButton. Here is my code:
[button setBackgroundImage:[UIImage imageNamed:#"button_image"] forState:UIControlStateNormal];
button.frame = CGRectMake(0.f, 0.f, 27.f, 27.f);
button.contentStretch = CGRectMake(13.f/27.f, 13.f/27.f, 1.f/27.f, 1.f/27.f);
[button setTitle:NSLocalizedString(#"long title", #"long title") forState:UIControlStateNormal];
[button sizeToFit];
CGRect buttonFrame = button.frame;
buttonFrame.size.width += 18.f * 2;
button.frame = buttonFrame;
But the result is no different from that without setting contentStretch at all.
So how to correctly use contentStretch to achieve what I want?
Please don't tell me again and again that I can achieve the same effect with stretchableImageWithLeftCapWidth:topCapHeight:. I know that and it's apparently not what I'm asking for. I just want to know how to properly use contentStretch. Thanks.
One issue I see is that you're dividing using integer division. 1 / 27 is equal to 0. 1.0 / 27.0 is equal to 0.037...
If all you want is a stretchable background on your button, check out stretchableImageWithLeftCapWidth:topCapHeight: on UIImage. Create the stretchable image that way, then set it to the background of your button.
I don't know the special behaviour with UIButtons (I'd also suggest to use stretchableImages there as it is a compound view). However, if you want to use contentStretch you could do so on an UIView given your data this was:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
view.layer.contents = (id)[[UIImage imageNamed:#"button_image"] CGImage];
view.contentStretch = CGRectMake(13./27., 13./27., 1./27., 1./27.);
This should be enough to have a UIView with a stretchable background.
Use -[UIImage stretchableImageWithLeftCapWidth:topCapHeight:].
I put this in the init method of a subclass of UIView:
// Add errorBackground & errorLabel.
rect.size.height = 26.0f;
errorBackground = [[UIImageView alloc] initWithFrame:rect];
errorBackground.image = [[UIImage imageNamed:#"ErrorBubble.png"]
stretchableImageWithLeftCapWidth:13 topCapHeight:0];
UILabel *errorLabel = [[UILabel alloc] initWithFrame:
CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height)];
errorLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
errorLabel.backgroundColor = [UIColor clearColor];
errorLabel.textAlignment = UITextAlignmentCenter;
errorLabel.font = [UIFont systemFontOfSize:14.0f];
errorLabel.text = #"1 Failed Passcode Attempt";
errorLabel.textColor = [UIColor whiteColor];
errorLabel.shadowColor = [UIColor blackColor];
errorLabel.shadowOffset = CGSizeMake(0.0f, -1.0f);
[errorBackground addSubview:errorLabel];
[errorLabel release];
[self addSubview:errorBackground];
ErrorBubble.png:
ErrorBubble#2x.png:
Unsatisfying but simple answer:
You can't, until Apple fixes this. IMO it's a long outstanding and very annoying bug.
The UIButton implementation consists of a couple of subviews, and the (internal) background view does not seem to reflect the settings done on the UIButton view.