iPhone UILabel animation - iphone

I have a UILabel and when the value change in the label, I want to highlight it's background color from another color and exists for 2,3 seconds and get back to normal color.
Anyone have an idea how to do this?

Add quartzCore as a framework
Add an import QuartzCore/QuartzCore.h
Use this code
- (void) initController
{
UIButton *myButton = [view viewWithTag:1]; // Just reference the button you have
[myButton addTarget:self action:#selector(animateLabel) forControlEvents:UIControlEventTouchUpInside];
}
- (void) animateLabel
{
CABasicAnimation* highlightAnim = [CABasicAnimation animationWithKeyPath:#"backgroundColor"];
highlightAnim.toValue = (id)[UIColor blueColor].CGColor;
highlightAnim.duration = 2; // In seconds
highlightAnim.autoreverses = YES; // If you want to it to return to the normal color
[label.layer addAnimation:highlightAnim forKey:nil];
}

Related

Increase UIButton's touch effect radius on highlight

Is there a way to increase UIButton's "glow effect" when Shows Touch on Highlight is enabled? In most of the cases it's fine on the iPhone, but way too small on the iPad. If it's not possible, any ideas how to achieve the desired behavior?
EDIT:
Basically, I'm looking for how to subclass UIButton to add this functionality.
I'll use something like this:
Add a target for button pressed on your button.
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
Here's the method that gets invoked when the button is pressed. You can change the shadowRadius to fit your needs.
- (void) buttonPressed:(id) sender
{
UIButton *button = (UIButton *) sender;
DDLogInfo(#"%# Button Pressed...", button.titleLabel.text);
UIColor *color = [UIColor whiteColor];
button.layer.shadowColor = [color CGColor];
button.layer.shadowRadius = 20.0f;
button.layer.shadowOpacity = 0.9;
button.layer.shadowOffset = CGSizeZero;
button.layer.masksToBounds = NO;
button.backgroundColor = [UIColor whiteColor];
}
You could create an image of the glow effect and add that to the button when its highlighted.

ExclusiveTouch per UIView

I have a two UIViews filled with UIButtons. I want to only allow one button to accept touches at a time PER UIView. That is to say I want multitouch working if you have one finger in each group of buttons but not if you have both fingers in the same group.
Of course exclusiveTouch set on the buttons makes sure only one button at a time is touched but it does it for the entire window. Is there a way to only allow one touch per UIView instead of the entire window?
Update: So to give a better understand of the desired function. I want a user to be able to select a red and blue card using multitouch. Easy. BUT I don't want them to be able to select two red cards or anything like that. Problem is if I turn on exclusiveTouch on the cards only one card in the WHOLE WINDOW can be selected at a time. The desired functionality is to have exclusiveTouch only operate PER UIVIEW which each set of cards is wrapped in its own UIView already.
Update 2: Just wanted to throw in that I am trying to find a solution that DOESN'T involve subclassing or otherwise overriding UIView's touch controllers. That is a last resort.
When touching down one of your buttons, you may set userInteractionEnabled property of another button to NO and set it back to YES while touching up.
UPDATE 1
Sorry, I was an idiot.
UPDATE 2
...
UPDATE 3
Finally I got back to XCode. This code works (if I understood your aim correctly):
#interface ViewController : UIViewController {
NSMutableArray *leftButtonsArray;
NSMutableArray *rightButtonsArray;
}
#end
//
#implementation ViewController
#pragma mark - Objects Processing
- (void)buttonDownAct:(UIButton *)sender {
sender.backgroundColor = [UIColor greenColor];
NSArray *targetArray = nil;
if ([leftButtonsArray indexOfObject:sender] == NSNotFound)
targetArray = rightButtonsArray;
else
targetArray = leftButtonsArray;
for (UIButton *button in targetArray)
if (button != sender)
button.userInteractionEnabled = NO;
}
- (void)buttonUpAct:(UIButton *)sender {
NSArray *targetArray = nil;
if ([leftButtonsArray indexOfObject:sender] == NSNotFound) {
targetArray = rightButtonsArray;
sender.backgroundColor = [UIColor blueColor];
}
else {
targetArray = leftButtonsArray;
sender.backgroundColor = [UIColor redColor];
}
for (UIButton *button in targetArray)
button.userInteractionEnabled = YES;
}
#pragma mark - View lifecycle
- (void)loadView {
leftButtonsArray = [[NSMutableArray alloc] init];
rightButtonsArray = [[NSMutableArray alloc] init];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view.backgroundColor = [UIColor whiteColor];
float desiredWidth = self.view.frame.size.width / 4, desiredHeight = self.view.frame.size.height / 2;
for (int i = 0; i < 4; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectInset(CGRectMake(desiredWidth * (i % 2), desiredHeight * (i / 2), desiredWidth, desiredHeight), 10, 10);
[button setBackgroundColor:[UIColor redColor]];
[button addTarget:self action:#selector(buttonDownAct:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:#selector(buttonUpAct:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[self.view addSubview:button];
[leftButtonsArray addObject:button];
}
for (int i = 0; i < 4; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectInset(CGRectOffset(CGRectMake(desiredWidth * (i % 2), desiredHeight * (i / 2), desiredWidth, desiredHeight), self.view.frame.size.width / 2, 0), 10, 10);
[button setBackgroundColor:[UIColor blueColor]];
[button addTarget:self action:#selector(buttonDownAct:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:#selector(buttonUpAct:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[self.view addSubview:button];
[rightButtonsArray addObject:button];
}
}
#end
Didnt try this, but anyway.
Can you make two UIView on the main view, one for red buttons and one for blue ones. And set exclusive touch for your buttons?

Method to create UIButtons

this is my first post, any help would be greatly appreciated.
I have to create a number of UIButtons programmatically, which I have done, but the code gets quite messy when there are alot of buttons so I have written a method that will take a UIbutton, string and UIcolor as input and set the rest of the UIButton attributes for me. The problem is the buttons don't seem to be created. Is what I'm trying possible or am I going about it the wrong way.
The method
-(void)makeButton:(UIButton *)name titleOfButton:(NSString *)title buttonColor:(UIColor *)color {
name =[[UIButton alloc] initWithFrame:(CGRectMake(400,400,150,100))];
[name setAlpha:(0.5)];
[name setBackgroundColor: color];
[name setTitle:title forState:UIControlStateNormal];
name.titleLabel.font = [UIFont systemFontOfSize:16];
name.titleLabel. numberOfLines = 0; // Dynamic number of lines
name.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
name.titleLabel.textColor = [UIColor blackColor];
[myView addSubview:name];
}
and to call the method
[self makeButton:JDLabel
titleOfButton:#"JD"
buttonColor:[UIColor redColor]];
The method has been declared in the header file and the buttons at the top of the class.
This is some code to get you started. This will work if you paste it to your view controller, generally put it in the view you want but change "self.view" to "self" or any view you want as long as you have the reference to it. Just call "addSomeButtons" on "viewDidLoad" or as some target..
- (void)buttonPressed:(UIButton *)sender {
NSLog(#"button %d pressed", sender.tag+1);
}
- (void)makeButtonWithtitle:(NSString *)title andColor:(UIColor *)color atPositionIndex:(NSInteger)index {
const CGFloat buttonHeight = 60.0f;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(.0f, buttonHeight*index, 300.0f, buttonHeight)];
button.tag = index;
[button setAlpha:(0.5)];
[button setBackgroundColor: color];
[button setTitle:title forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:16];
button.titleLabel. numberOfLines = 0; // Dynamic number of lines
button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
button.titleLabel.textColor = [UIColor blackColor];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
[button release];
}
- (void)addSomeButtons {
for(int i=0; i<10; i++) {
[self makeButtonWithtitle:[NSString stringWithFormat:#"button %d", i+1] andColor:[UIColor greenColor] atPositionIndex:i];
}
}
Anyway what you are trying to do is very common and very possible. For instance I never ever ever use the interface builder.
set the different tag value of to separate the button from another button like:
button.tag = 1;
here you should use variable like
in .h
int i ;
in .m
button.tag = i;
and set the frame size of one button to another button
UIButton *name = [UIButton buttonWithType:UIButtonTypeRoundRectangle];
name.frame = CGRectMake(10*i,10*i,150,100);
i++;
UIButtons are getting created but getting overlapped over each other.. u just need to change the frame with every method call too.. 400,400 will create the button off screen .. i don't think thats what u want .. try something like 160,240
You might want to consider creating the Buttons in Interface Builder, which I find much more convenient for setting the size, colors etc.
You can then reference the buttons in the code via either with an IBOutlet per Button or with an IBOutletCollection, which let's you "group" a number of UIViews in one Outlet:
Simply create your UIButtons in Interfacebuilder and place them next to your main view, so that they won't be displayed initially.
CMD + Click all buttons and CTRL + Drag to your .h file and create an IBOutletCollection which will eventually look like this in your code:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *allMyButtonsFromIB;
Now you can access the buttons in the implementation via self.allMyButtons, which is an NSArray
-(void)createButtonWithTitle:(NSString*)title andColor:(UIColor*)color andFrame:(CGRect)frame{
UIButton *lButton = [UIButton buttonWithType:UIButtonTypeCustom];
[lButton setFrame:frame];
[lButton setTitle:title forState:UIControlStateNormal];
lButton.titleLabel.font = [UIFont systemFontOfSize:16];
[lButton setBackgroundColor:color];
[self.view addSubview:lButton];
lButton = nil;
}
You can change the frame values to put the buttons at appropriate positions on the view.

Animating UIButton background image

Is there a way to animate a UIButton background image view with a set of images?
I've managed to do so with the imageView property, but couldn't find an equivalent background property.
10x
Here's what I did (inside a UIButton subclass):
Set the button images, like regular:
[self setBackgroundImage:[[UIImage imageNamed:#"button"] resizableImageWithCapInsets:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)] forState:UIControlStateNormal];
[self setBackgroundImage:[[UIImage imageNamed:#"button_pressed"] resizableImageWithCapInsets:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)] forState:UIControlStateHighlighted];
Override highlighted:
- (void)setHighlighted:(BOOL)highlighted {
[UIView transitionWithView:self duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowAnimatedContent animations:^{
[super setHighlighted:highlighted];
} completion:nil];
}
To change a buttons backround image, or text for that matter - you need to change it for the particular UIControlState... i.e Highlighted, Selected, Disabled
Use
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state
I'm not sure if you can animate them, I've never tried. If you can't animate them, then you could put a UIImageView behind a transparent button and animate the images in that instead - just a thought.
You can animate an UIButton the way you animate an UIImageView like this...
-(void) addAnimationToButton:(UIButton*) button{
UIImageView* animationView = [button imageView];
NSArray* animations=[NSArray arrayWithObjects:
[UIImage imageNamed:#"sprite1.png"],
[UIImage imageNamed:#"sprite2.png"],
[UIImage imageNamed:#"sprite2.png"],
//and so on if you need more
nil];
CGFloat animationDuration = 2.0;
[animationView setAnimationImages:animations];
[animationView setAnimationDuration:animationDuration];
[animationView setAnimationRepeatCount:0]; //0 is infinite
}
And you use it like this:
[self addAnimationToButton:yourButton];
[[yourButton imageView] startAnimating]; //or stopAnimating
Yes it is possible. Use NSTimer ,
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:5.00 target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
then, method is as follows,
- (void)changeImage
{
static int counter = 0;
if([bannerArray count] == counter)
{
counter = 0;
}
[button setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:bannerArray[counter]]]] forState:UIControlStateNormal];
counter++;
}
It worked for me. But adding animation like flip etc need to figure out. Hope this also one way to help your need.

iPhone : How to set BackgroundColor of UIButton with buttonType UIButtonTypeCustom

i want to change the button color when it is clicked. I used :
[button setBackgroundColor:[UIColor redColor]];
but this shows red color only on the four corners of button not on the whole button and also when i use forState:UIControlStateNormal then the application hangs.
Is their any way to show some color on button when clicked?
[click1 setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
Any help will be appreciated.
You could create an image programmatically and so have the ability to use your colors in a dynamic way:
Create a category for UIButton with this method and be sure to have QuartzCore lib imported via #import QuartzCore:
- (void)setColor:(UIColor *)color forState:(UIControlState)state
{
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
colorView.backgroundColor = color;
UIGraphicsBeginImageContext(colorView.bounds.size);
[colorView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:colorImage forState:state];
}
This is gonna create an image with the size of your button for your specified color and then assigning it for the wished state. Because of the usage of the backgroundImage you can still set a title for the button via the setTitle:forState: method.
This is what I do ... it's a custom subclass of a UIButton, just set the normal and highlighted colors and everything shpould work fine ;)
Header file:
//
// FTCustomButton.h
// FTLibrary
//
// Created by Ondrej Rafaj on 14/01/2013.
// Copyright (c) 2013 Fuerte International. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FTCustomButton : UIButton
#property (nonatomic, strong, readonly) UIColor *normalColor;
#property (nonatomic, strong, readonly) UIColor *highlightedColor;
- (void)setNormalColor:(UIColor *)normalColor;
- (void)setHighlightedColor:(UIColor *)highlightedColor;
#end
This is the implementation file:
//
// FTCustomButton.m
// FTLibrary
//
// Created by Ondrej Rafaj on 14/01/2013.
// Copyright (c) 2013 Fuerte International. All rights reserved.
//
#import "FTCustomButton.h"
//*****************************************************************************
// private interface declaration
//*****************************************************************************
#interface MCSelectionButton ()
#property(nonatomic, strong, readwrite) UIColor *normalColor;
#property(nonatomic, strong, readwrite) UIColor *highlightedColor;
#end
//*****************************************************************************
// public interface implementation
//*****************************************************************************
#implementation FTCustomButton
#pragma mark Settings
- (void)setNormalColor:(UIColor *)normalColor {
[self setBackgroundColor:normalColor];
_normalColor = normalColor;
}
- (void)setHighlightedColor:(UIColor *)highlightedColor {
_highlightedColor = highlightedColor;
}
#pragma mark Actions
- (void)didTapButtonForHighlight:(UIButton *)sender {
[self setBackgroundColor:_highlightedColor];
}
- (void)didUnTapButtonForHighlight:(UIButton *)sender {
[self setBackgroundColor:_normalColor];
}
#pragma mark Initialization
- (void)setupButton {
[self addTarget:self action:#selector(didTapButtonForHighlight:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:#selector(didUnTapButtonForHighlight:) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:#selector(didUnTapButtonForHighlight:) forControlEvents:UIControlEventTouchUpOutside];
}
- (id)init {
self = [super init];
if (self) {
[self setupButton];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setupButton];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupButton];
}
return self;
}
#end
Make sure the button type is custom as someone else already stated. Then doing the following will bring back those rounded corners:
[self.myButton.layer setCornerRadius:8.0f];
[self.myButton.layer setMasksToBounds:YES];
[self.myButton.layer setBorderWidth:1.0f];
[self.myButton.layer setBorderColor:[[UIColor whiteColor] CGColor]];
self.myButton.backgroundColor = [UIColor redColor];
Though, personally, I'm a big fan of gradient buttons over solid colors... also, background color doesn't have different states, whereas background images do:
[self.myButton setBackgroundImage:[UIImage imageNamed:#"gradient.png"] forState:UIControlStateNormal];
Using an image, your button will darken with selection (or you could provide a different background image per state to do something different). This won't happen with background color, the background will always stay the same, only your button label changing per state.
Completing Dima answer, I've implemented an extension in Swift:
extension UIButton {
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
self.setBackgroundImage(imageWithColor(color), forState: state)
}
}
I believe a more efficient solution than any of the ones listed is to just draw the image in Core Graphics directly. You avoid having to make a UIView and calling renderInContext:, which can be pretty slow.
+ (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;
}
You can use this in a UIImage category to create an image to use in a UIButton.
you have take a red color image for your button and then you can set it when user clicks
[yourButtonName setBackgroundImage:[UIImage imageNamed:#"yourRedButton.png"] forState:UIControlStateHighlighted];
To get a button with a single color you can set the button to custom button.
Here is my known list of available button api (you can set them in viewDidLoad after setting them as outlets).
Just import quartz and change the border radius to make it look like a button.
//highlightcolor - this changes the status for UIControlStateHighlighted
OUTLETNAME.tintColor = [UIColor orangeColor];
//borderradius *quartz
[[OUTLETNAME layer] setCornerRadius:20.0f];
//border *quartz
[[OUTLETNAME layer] setBorderWidth:5.0f];
//bordercolor
[OUTLETNAME.layer setBorderColor:[[UIColor greenColor] CGColor]];
//backgroundcolor
OUTLETNAME.backgroundColor = [UIColor blackColor];
//image
[OUTLETNAME setImage:[UIImage imageNamed:PICNAME] forState:UIControlStateNormal];
//text
[OUTLETNAME setTitle:#"TEXT" forState:UIControlStateNormal];
//fontsize
OUTLETNAME.titleLabel.font = [UIFont systemFontOfSize:36.0];
//fontcolor
OUTLETNAME.titleLabel.textColor = [UIColor blackColor];
//fontcolor
[OUTLETNAME setTitleColor:[UIColor orangeColor] forState: UIControlStateNormal];
If you want custom buttons with a gradient color you have to make a custom button class.
This blog has a glossy button class project for download.
http://didikot.com/?p=217
You have to refractor and convert to ARC to use it, I think.
This blog does the same thing but without the gloss.
http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
#pankaj Gyani says correct
UIButton *button = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame:CGRectMake(0, 0, 24, 24)];
[button addTarget:self action:#selector(prevButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"IntroArrowLeft.png"] forState:UIControlStateNormal];
[self addSubview:button];
You should set UIButton's type to custom and set its image or background image properties for normal and highlighted states.
For professional and nice looking buttons that you can easily use in your apps this custom button component may also help.
You have everything correct. Just set your button type to UIButtonTypeCustom..
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(200, 8, 100, 30);
[button setTitle:#"Set up" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor greenColor]];
button.clipsToBounds = YES;
button.layer.cornerRadius = 10;
button.alpha = 0.5;
Just an update to Hendrik answer.
To work well with Auto Layout you need to set UIView frame size to button intrinsicContentSize, otherwise it will screw up layout.
- (void)setColor:(UIColor *)color forState:(UIControlState)state
{
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.intrinsicContentSize.width, self.intrinsicContentSize.height)];
colorView.backgroundColor = color;
UIGraphicsBeginImageContext(colorView.bounds.size);
[colorView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:colorImage forState:state];
}
Make the button type as custom.
Eg
button = [UIButton buttonWithType:UIButtonTypeCustom];
All the best.
Thanks to #Dima
Here is an updated code for swift 3.0 as UIButton extension
extension UIButton {
// thanks to #Dima http://stackoverflow.com/a/24665476/2581637 update code for swift 3
func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
func imageWithColor(color: UIColor) -> UIImage? {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.fill(rect)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
self.setBackgroundImage(imageWithColor(color: color), for: state)
}
}
In .xib - set Button Type: Custom.
Set Background Color as per you want.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[button1 setBackgroundColor:[UIColor redColor]];