UIButton border that changes thickness when selected - ios

I have a subclassed UIButton
- (void)configureButton
{
self.titleLabel.font = [UIFont systemFontOfSize:18.0f];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
CALayer *border = [CALayer layer];
border.backgroundColor = [UIColor whiteColor].CGColor;
border.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width, 1.0);
[self.layer addSublayer:border];
}
- (void)setSelected:(BOOL)selected
{
[super setSelected:selected];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
// remove all layers ?
if (selected) {
CALayer *border = [CALayer layer];
border.backgroundColor = [UIColor whiteColor].CGColor;
border.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width,3.0);
[self.layer addSublayer:border];
self.titleLabel.font = [UIFont boldSystemFontOfSize:18.0f];
} else {
CALayer *border = [CALayer layer];
border.backgroundColor = [UIColor whiteColor].CGColor;
border.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width,1.0);
[self.layer addSublayer:border];
self.titleLabel.font = [UIFont systemFontOfSize:18.0f];
}
}
The default state of the button has a 1.0 bottom border. When it is selected, the border should become 3.0. How can I clear the previously added layer and re add a 1.0 border when a user toggles a button?

I believe there is an easier way to do what you need. If you subclass the UIButton just because you just want to have different types button border, you can try a different way but a lot easier.
Use 2 different button background image, one with border 1 and another with border 3.
[self.button setBackgroundImage:[UIImage imageNamed:#"ImageWithBorder1"] forState:UIControlStateNormal];
[self.button setBackgroundImage:[UIImage imageNamed:#"ImageWithBorder3"] forState:UIControlStateHighlighted];
[self.button setBackgroundImage:[UIImage imageNamed:#"ImageWithBorder3"] forState:UIControlStateSelected];
With an additional button image, it might just take extra 10 kb on your project.

Related

iOS: UIButton draw circle border in iOS

I need to draw a circle like border outside UIButton. Below is the attach image and code. I also need to show text below button. Following code will add image and text beneath that. But how do I have layer.
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setBackgroundImage:image forState:UIControlStateNormal];
imageButton.translatesAutoresizingMaskIntoConstraints = NO;
imageButton.backgroundColor = [UIColor clearColor];
[imageButton setTitle:title forState:UIControlStateNormal];
imageButton.titleLabel.textAlignment = NSTextAlignmentCenter;
imageButton.titleLabel.font = [UIFont fontWithName:#"OpenSans" size:fon];
[imageButton setTitleEdgeInsets:UIEdgeInsetsMake(95, 0.0f, 0.0f, 0.0f)];
[imageButton setTitleColor:[UIColor iconTextColor] forState:UIControlStateNormal];
[imageButton addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
set the button width and height ex : width =100 and height = 100, should be same if you want a round then,
imageButton.layer.cornerRadius = 50 // this value should be half from width or height (width = height)
imageButton.layer.masksToBounds = YES
//if you want border with above
imageButton.layer.borderWidth = 1;
imageButton.layer.borderColor = [[UIColor blackColor] CGColor];
You can do something like this.
borderView = UIView()
yourButton = UIButton()
borderView.frame.size.width = yourButton.frame.size.width + 1
borderView.layer.cornerRadius = borderView.frame.size.width/2
borderView.clipToBounds = true
borderView.backgroundColor = UIColor.clearColor()
borderView.layer.borderWidth = 1
borderView.layer.borderColor = UIColor.blueColor()

UIButton shadow layer effect

I am creating a UIButton similar to this image:
I tried it by using following code:
+(void)createShadowOnView:(UIView *)view color:(UIColor *)color width:(CGFloat)width height:(CGFloat)height shadowOpacity:(CGFloat)shadowOpacity andShadowRadius:(CGFloat)radius{
view.layer.masksToBounds = NO;
view.layer.shadowColor = color.CGColor;
view.layer.shadowOffset = CGSizeMake(width,height);
view.layer.shadowOpacity = shadowOpacity;
[view.layer setShadowRadius:radius];
}
I was able to achieve this:
I want shadow effect on Button to be kept only on bottom part.
How can I achieve desired effect.
Maybe you should set view's backgroundcolor, so the title has no shadow, you can set view.layer.shadowOffset to change the shadow size.
UIButton *customBTn = [UIButton buttonWithType:UIButtonTypeCustom];
customBTn.backgroundColor = [UIColor whiteColor];
customBTn.frame = CGRectMake(100, 100, 200, 50);
[customBTn setTitle:#"Sign Up" forState:UIControlStateNormal];
[customBTn setTitleColor:[UIColor colorWithRed:1/255.0 green:168/255.0 blue:244/255.0 alpha:1.0] forState:UIControlStateNormal];
customBTn.layer.borderColor = [UIColor colorWithRed:1/255.0 green:168/255.0 blue:244/255.0 alpha:1.0].CGColor;
customBTn.layer.borderWidth = 2;
customBTn.layer.cornerRadius = 25;
customBTn.layer.shadowColor = [UIColor lightGrayColor].CGColor;
customBTn.layer.shadowOffset = CGSizeMake(0,8);
customBTn.layer.shadowOpacity = 0.9;
[self.view addSubview:customBTn];
Output :-
Only issue with your code is you missed to set background colour for your sign up button. Use this code,
self.signUpButton.backgroundColor = [UIColor whiteColor];
[UIView createShadowOnView:self.signUpButton color:[UIColor lightGrayColor] width:0 height:2 shadowOpacity:0.3 andShadowRadius:0];
Preview:
Code:
UIButton *buttonWithShadow = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonWithShadow setFrame:CGRectMake(10.0f, 10.0f, 300.0f, 50.0f)];
[buttonWithShadow setTitle:#"SIGN UP" forState:UIControlStateNormal];
[buttonWithShadow setTitle:#"SIGN UP" forState:UIControlStateHighlighted];
[buttonWithShadow.titleLabel setFont:[UIFont boldSystemFontOfSize:15.0f]];
[buttonWithShadow setTitleColor:[UIColor colorWithRed:1.0f/255.0 green:168.0f/255.0 blue:244.0f/255.0 alpha:1.0f] forState:UIControlStateNormal];
[buttonWithShadow setBackgroundColor:[UIColor whiteColor]];
[buttonWithShadow.layer setBorderColor:[UIColor colorWithRed:1.0f/255.0 green:168.0f/255.0 blue:244.0f/255.0 alpha:1.0f].CGColor];
[buttonWithShadow.layer setBorderWidth:2.0f];
[buttonWithShadow.layer setCornerRadius:(buttonWithShadow.frame.size.height / 2.0f)];
[buttonWithShadow.layer setShadowColor:[UIColor lightGrayColor].CGColor];
[buttonWithShadow.layer setShadowOpacity:0.3f];
[buttonWithShadow.layer setShadowRadius:0.0f];
[buttonWithShadow.layer setShadowOffset:CGSizeMake(0.0f,2.0f)];
[buttonWithShadow.layer setMasksToBounds:NO];
[self.view addSubview:buttonWithShadow];

Shadow on UIButton text only (not background)

I have a set of UIButtons with background colors. when the user taps one, I want only the button's text to have a shadow all around it (to show that it has been selected). However, when I add the shadow, the shadow appears over the whole button (background and all), and not just the text. Is there an easier workaround to this than just adding a UILabel over a blank button?
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
...
[button setBackgroundColor:[UIColor blueColor]];
[button.layer setShadowRadius:8.0];
[button.layer setShadowColor:[[UIColor orangeColor] CGColor]];
[button.layer setShadowOpacity:0];
...
Here is the simple way to add shadow to the button title with shadow radius property available in Objective-C:
#import <QuartzCore/QuartzCore.h>
button.titleLabel.layer.shadowOffset = CGSizeMake(2.0, 2.0);
button.titleLabel.layer.shadowColor = [UIColor colorWithWhite:0.1 alpha:0.7].CGColor;
button.titleLabel.layer.shadowRadius = 2.0;
button.titleLabel.layer.shadowOpacity = 1.0;
button.titleLabel.layer.masksToBounds = NO;
Swift ..
Say you override the UIButton class ..
titleLabel!.layer.shadowColor = UIColor.black.cgColor
titleLabel!.layer.shadowOffset = CGSize(width: -0.5, height: 0.5)
titleLabel!.layer.shadowOpacity = 1.0
titleLabel!.layer.shadowRadius = 0
titleLabel!.layer.masksToBounds = false
You need to use setTitleShadowColor: forState: and shadowOffset property of UIButton.
below code will add shadow only to button label whenever user tap on button.
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setBackgroundColor:[UIColor blueColor]];
button.frame = CGRectMake(50, 70, 200, 100);
[button setTitle:#"Test Button" forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont systemFontOfSize:45]];
[button setTitleShadowColor:[UIColor redColor] forState:UIControlStateHighlighted];
[button.titleLabel setShadowOffset:CGSizeMake(2.0, 2.0)];
Hope this will help.
Just set the shadow on the titleLabel property of the UIButton rather than what you're doing now.
eg
button.titleLabel.shadowColor = ((selectionState) ?[UIColor orangeColor] : [UIColor clearColor] );
button.titleLabel.shadowOffset = CGSizeMake (1.5,1.5);
For 2018
This does not work. Use the answer of #Userich
One way to do this is to use attributed strings for the normal and highlighted titles. You can create an NSShadow object, and assign that as the value for the NSShadowAttributeName. This gives you control over the properties of the shadow. To keep the title from dimming, you should set the button type to Custom instead of System.
- (void)viewDidLoad {
[super viewDidLoad];
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor darkGrayColor];
shadow.shadowOffset = CGSizeMake(2, 2);
shadow.shadowBlurRadius = 2;
NSString *titleString = #"Title";
NSAttributedString *normalTitle = [[NSAttributedString alloc] initWithString:titleString];
NSAttributedString *highlightedTitle = [[NSAttributedString alloc] initWithString:titleString attributes:#{NSShadowAttributeName:shadow}];
[self.button setAttributedTitle:normalTitle forState:UIControlStateNormal];
[self.button setAttributedTitle:highlightedTitle forState:UIControlStateHighlighted];
}

iOS UIButton with transparent title on white background

I have a custom UIButton with transparent background and white title.
I'm looking for a simple solution to invert it on highlight (white background and transparent title) as it is achieved on system UISegmentedControl.
Is there simpler solution than inverting alpha on snapshot used as a CALayer mask?
If not, could you tell how can I invert CALayer alpha?
You can draw the text on a CGContext using Destination Out as blend mode.
This code seems to work:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
UIFont* font = [UIFont fontWithName:#"Helvetica-Bold" size:18];
NSString* buttonText = #"BUTTON";
CGSize buttonSize = CGSizeMake(200, 50);
NSDictionary* textAttributes = #{NSFontAttributeName:font};
CGSize textSize = [buttonText sizeWithAttributes:textAttributes];
UIGraphicsBeginImageContextWithOptions(buttonSize, NO, [[UIScreen mainScreen] scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, buttonSize.width, buttonSize.height)];
CGContextAddPath(ctx, path.CGPath);
CGContextFillPath(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut);
CGPoint center = CGPointMake(buttonSize.width/2-textSize.width/2, buttonSize.height/2-textSize.height/2);
[#"BUTTON" drawAtPoint:center withAttributes:textAttributes];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView* imgView = [[UIImageView alloc] initWithImage:viewImage];
[self.view addSubview:imgView];
}
By the way, if you want to set the UIImage in a UIButton instead of just adding it to a view:
UIButton* boton = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, viewImage.size.width, viewImage.size.height)];
[boton setBackgroundColor:[UIColor clearColor]];
[boton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
boton.titleLabel.font = font;
[boton setTitle:buttonText forState:UIControlStateNormal];
[boton setImage:viewImage forState:UIControlStateHighlighted];
[self.view addSubview:boton];
You could set
-(void)viewDidload: {
[yourButton setTitleColor:(UIColor *)color
forState:UIControlStateHighlighted];
[yourButton addTarget:self
action:#selector(changeButtonBackGroundColor:)
forControlEvents:UIControlEventTouchDown];
}
-(void)changeButtonBackGroundColor:(UIButton *)button {
[button setBackgroundColor:[UIColor yourColor]];
}
remember to change it back with events: UIControlEventTouchUpInside and UIControlEventTouchOutSide :)

Touch another UITextField don't work (sometimes)

I have 2 textfields. On startup I can switch between lbl and lbl2. But after the first click only lbl is working, you have to tap 10(+/-) times on lbl2 before the cursor goes to that textfield. Whats going on?
- (void)viewWillAppear:(BOOL)animated
{
UITextField *lbl = [[UITextField alloc] initWithFrame:CGRectMake(24, 397, 266, 30)];
[lbl setPlaceholder:#"E-mailadres"];
[lbl setValue:[UIColor whiteColor] forKeyPath:#"_placeholderLabel.textColor"];
[lbl setBackgroundColor:[UIColor clearColor]];
lbl.textColor = [UIColor whiteColor];
[[self view] addSubview:lbl];
CALayer* layer = [lbl layer];
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor whiteColor].CGColor;
bottomBorder.borderWidth = 1;
bottomBorder.frame = CGRectMake(-1, layer.frame.size.height-1, layer.frame.size.width, 1);
[bottomBorder setBorderColor:[UIColor whiteColor].CGColor];
[layer addSublayer:bottomBorder];
UITextField *lbl2 = [[UITextField alloc] initWithFrame:CGRectMake(24, 450, 266, 30)];
[lbl2 setPlaceholder:#"Wachtwoord"];
[lbl2 setValue:[UIColor whiteColor] forKeyPath:#"_placeholderLabel.textColor"];
[lbl2 setBackgroundColor:[UIColor clearColor]];
lbl2.textColor = [UIColor whiteColor];
lbl2.secureTextEntry = YES;
[[self view] addSubview:lbl2];
CALayer* layer2 = [lbl2 layer];
CALayer *bottomBorder2 = [CALayer layer];
bottomBorder2.borderColor = [UIColor whiteColor].CGColor;
bottomBorder2.borderWidth = 1;
bottomBorder2.frame = CGRectMake(-1, layer2.frame.size.height-1, layer2.frame.size.width, 1);
[bottomBorder2 setBorderColor:[UIColor whiteColor].CGColor];
[layer2 addSublayer:bottomBorder2];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(24, 500, 266, 30); // position in the parent view and set the size of the button
[myButton setTitle:#"INLOGGEN" forState:UIControlStateNormal];
[myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// add targets and actions
// add to a view
[[self view] addSubview:myButton];
CALayer *layer3 = myButton.layer;
layer3.backgroundColor = [[UIColor whiteColor] CGColor];
layer3.borderColor = [[UIColor whiteColor] CGColor];
layer3.borderWidth = 1.0f;
layer3.opacity = 0.6;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}
It appears neither text field was given a delegate. I'm not sure you can use them without one - I never tried. If you don't have a delegate how would you dismiss the keyboard at the end of the editing session?

Resources