Shadow on UIButton text only (not background) - ios

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];
}

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()

Button Text not showing

When I try to post the following code, my app just shows an empty rectangle where the button's text should be. I am a beginner at xcode and I have determined this code from other tutorials.
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *player1 = [[UILabel alloc]initWithFrame:CGRectMake(35, 120,130, 30)];
[player1 setText:#"Player"];
player1.layer.borderWidth = 1.0;
player1.layer.borderColor = [UIColor blackColor].CGColor;
player1.textAlignment = UITextAlignmentCenter;
[self.view addSubview: player1];
UIButton *score1 = [[UIButton alloc]initWithFrame:CGRectMake(165, 120, 60, 30)];
[score1 setTitle:#"0" forState:UIControlStateNormal];
score1.layer.borderWidth = 1.0;
score1.layer.borderColor = [UIColor blackColor].CGColor;
[self.view addSubview: score1];
UILabel *player2 = [[UILabel alloc]initWithFrame:CGRectMake(35, 150, 130, 30)];
[player2 setText:#"Opponent"];
player2.layer.borderWidth = 1.0;
player2.layer.borderColor = [UIColor blackColor].CGColor;
player2.textAlignment = UITextAlignmentCenter;
[self.view addSubview: player2];
}
Like I said, everything but the text in the button is showing up.
The reason why the button looks blank is because its text color is actually white. Just give it a different color and 0 will now show:
score1.layer.backgroundColor = [UIColor blackColor].CGColor;
If you don't want to change the button background color, you may want to set the text color:
[score1 setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
Read Question: [initWithFrame:frame] vs. [UIButton buttonWithType], for more about creating a UIButton with these different methods.
The problem is the way you're creating the button:
UIButton *score1 = [[UIButton alloc]initWithFrame:CGRectMake(165, 120, 60, 30)];
That's not how you do it. Do it like this:
UIButton *score1 = [UIButton buttonWithType:UIButtonTypeSystem];
score1.frame = CGRectMake(165, 120, 60, 30);
All will be well after that!

iOS 7/8 Passcode screen visual effect

Wondering if anyone has any insight on how this effect is achieved. Specifically the circles around the numbers, how you can see through the rim of the circle onto the blurred background behind it. And the brightness is maintained even after the dark overlay appears on the layer between the numbers and the original background.
This is the screen that is presented when the user attempts to unlock their iPhone.
In iOS 8 this can be done with UIVibrancyEffect:
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *viewWithBlurredBackground = [[UIVisualEffectView alloc] initWithEffect:effect];
viewWithBlurredBackground.frame = self.view.bounds;
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:effect];
UIVisualEffectView *viewWithVibrancy = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
viewWithVibrancy.frame = self.view.bounds;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = 40;
button.layer.borderWidth = 1.2;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.frame = CGRectMake(100, 100, 80, 80);
[viewWithVibrancy.contentView addSubview:button];
[viewWithBlurredBackground.contentView addSubview:viewWithVibrancy];
[self.view addSubview:viewWithBlurredBackground];
NSMutableAttributedString *titleString = [[NSMutableAttributedString alloc] initWithString:#"2\nA B C"];
[titleString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:(NSRange){0, titleString.length}];
[titleString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Thin" size:32] range:[titleString.string rangeOfString:#"2"]];
[titleString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Thin" size:10] range:[titleString.string rangeOfString:#"A B C"]];
// Add UILabel on top of the button, in order to avoid UIVibrancyEffect for text.
// If you don't need it, just call [button setAttributedTitle:titleString forState:UIControlStateNormal];
UILabel *notVibrancyLabel = [[UILabel alloc] init];
notVibrancyLabel.attributedText = titleString;
notVibrancyLabel.textAlignment = NSTextAlignmentCenter;
notVibrancyLabel.numberOfLines = 2;
notVibrancyLabel.frame = button.frame;
[self.view addSubview:notVibrancyLabel];
Also you need change background color when button is pressed.
- (void)buttonPressed:(id)sender
{
UIButton *button = sender;
// Of course, this is just an example. Better to use subclass for this.
[UIView animateWithDuration:0.2 animations:^
{
button.backgroundColor = [UIColor whiteColor];
} completion:^(BOOL finished)
{
[UIView animateWithDuration:0.2 animations:^
{
button.backgroundColor = [UIColor clearColor];
}];
}];
}
Result:

UIButton's title property logs correctly but not showing up when adding button as subview

I have a UIButton that I have created, and I can successfully add it as a subview and see it on the screen. The problem is, when I try using:
[myButton setTitle:#"My Title" forState:UIControlStateNormal];
The button does not show a title when I run the app. If I NSLog the button's title after using the above method, it has in fact been set to the title that I'm passing in.
Here's my code. This is inside a UIView subclass. I realize that some of this logic might not belong in a UIView subclass but I'm just trying to get this to work as fast as possible:
// Set the view's frame, background color, corner radius
self.frame = CGRectMake(45, 200, 235, 187);
self.backgroundColor = [UIColor whiteColor];
self.layer.borderWidth = 1;
self.layer.borderColor = [UIColor grayColor].CGColor;
self.layer.cornerRadius = 5;
// Create the popup's body text label
self.popupBodyTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 150)];
self.popupBodyTextLabel.text = #"Text goes here.";
// Add text view to popup's subviews
[self addSubview:self.popupBodyTextLabel];
// Create ok button
UIButton *myButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 143, 120, 44)];
myButton.backgroundColor = [UIColor whiteColor];
myButton.layer.borderWidth = 1;
myButton.layer.borderColor = [UIColor grayColor].CGColor;
[myButton setTitle:#"OK" forState:UIControlStateNormal];
// Round the button's bottom left corner
UIBezierPath *myButtonMaskPath = [UIBezierPath bezierPathWithRoundedRect:myButton.bounds byRoundingCorners:(UIRectCornerBottomLeft) cornerRadii:CGSizeMake(5.0, 5.0)];
CAShapeLayer *okButtonMaskLayer = [[CAShapeLayer alloc] init];
myButtonMaskLayer.frame = myButton.bounds;
myButtonMaskLayer.path = myButtonMaskPath.CGPath;
myButton.layer.mask = myButtonMaskLayer;
// Add selector to button
[myButton addTarget:self action:#selector(myButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
// Add button to subviews
[self addSubview:myButton];
// Create the background view
self.backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
self.backgroundView.backgroundColor = [UIColor grayColor];
self.backgroundView.alpha = 0.5f;
// Show our new views
[[[UIApplication sharedApplication] keyWindow] addSubview:self.backgroundView];
[[[UIApplication sharedApplication] keyWindow] addSubview:[MPPopupView shared]];
The code for setting button title is right, so use this code to set title color
[myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

How to change clear button image (x button) or atleast the color of the clear button image in UISearchbar?

I need a fully transparent searchbar with cancel button. I have tried many solutions But I couldnt find a better solution yet. When I try to remove background color it shows scope bar. Can any one give me some source code for fully transperant Searchbar with can button.
Here's
addSearchbar.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5];
UITextField *sbTextField = (UITextField *)[self.addSearchbar.subviews lastObject];
for (UIView *subview in addSearchbar.subviews)
{
NSLog(#"%#",subview);
if ([subview isKindOfClass:[UITextField class]])
{
sbTextField = (UITextField *)subview;
UIImage *image = [UIImage imageNamed: #"06_magnifying_glass.png"];
UIImageView *iView = [[UIImageView alloc] initWithImage:image];
iView.frame = CGRectMake(0, 0, 24, 24);
sbTextField.leftView.frame = CGRectMake(0, 0, 24, 24);
sbTextField.leftView = iView;
[sbTextField.rightView removeFromSuperview];
CGFloat myWidth = 24.0f;
CGFloat myHeight = 24.0f;
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, myWidth, myHeight)];
[myButton setImage:[UIImage imageNamed:#"clear.png"] forState:UIControlStateNormal];
[myButton setImage:[UIImage imageNamed:#"clear.png"] forState:UIControlStateHighlighted];
[myButton addTarget:self action:#selector(doClear:) forControlEvents:UIControlEventTouchUpInside];
sbTextField.rightView = myButton;
sbTextField.rightViewMode = UITextFieldViewModeWhileEditing;
break;
}
if([subview isMemberOfClass:[UISegmentedControl class]])
{
UISegmentedControl *scopeBar=(UISegmentedControl *) subview;
scopeBar.tintColor = [UIColor clearColor];
}
}
[sbTextField removeFromSuperview];
[addSearchbar addSubview:sbTextField];
[addSearchbar setSearchFieldBackgroundImage:[UIImage imageNamed:#"SearchBar.png"] forState:UIControlStateNormal];
CGRect sbFrame = self.addSearchbar.frame;
// Set the default height of a textfield
sbFrame.size.height = 31;
/* 8 is the top padding for textfield inside searchbar
* You may need to add a variable to 8 according to your requirement.
*/
sbFrame.origin.y = 6+self.addSearchbar.frame.origin.y;
sbTextField.frame = sbFrame;
sbTextField.textColor = [UIColor lightGrayColor];
[sbTextField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];
Need a fully transparent searchbar with cancel button and clear button but without scopebar.
Thanks in advance
As of iOS 5.0 you can do the following:
UIImage *imgClear = [UIImage imageNamed:#"clear"];
[addSearchBar setImage:imgClear forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
Thats it. You might also want to repeat the line for the UIControlStateHighlighted state.
The last thing you should be doing is digging around inside the subviews of the search bar. It is guaranteed to break some day. Use the proper API to customize any control.
See that you set the UIControlHighlighted state image first and then the UIControlStateNormal state image or else you might face an issue wherein the clearIcon is not set in the highlighted state. (Not sure why this problem occurs.)
[_searchBar setImage:[UIImage imageNamed:#"ClearIcon"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateHighlighted];
[_searchBar setImage:[UIImage imageNamed:#"ClearIcon"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
For those of you trying this in Swift (I know someone is going to come here looking for this...) here you go:
self.searchBar.setImage(UIImage(named: "ico-cancel"), forSearchBarIcon: UISearchBarIcon.Clear, state: UIControlState.Normal)
self.searchBar.setImage(UIImage(named: "ico-cancel"), forSearchBarIcon: UISearchBarIcon.Clear, state: UIControlState.Highlighted)
Make sure you have the correct image in your Assets.xcassets folder.
Here’s how you change the magnifying glass and clear button icon in a UISearchBar’s UITextField
Without New Icons:
// Reference search display controller search bar's text field (in my case).
UITextField *searchBarTextField = [self.searchDisplayController.searchBar valueForKey:#"_searchField"];
// Magnifying glass icon.
UIImageView *leftImageView = (UIImageView *)searchBarTextField.leftView;
leftImageView.image = [LeftImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
leftImageView.tintColor = [UIColor whiteColor];
// Clear button
UIButton *clearButton = [searchBarTextField valueForKey:#"_clearButton"];
[clearButton setImage:[clearButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
clearButton.tintColor = [UIColor whiteColor];

Resources