UISlider unwanted behaviour while animating - ios

I am using a UISlider in my app where I add max and min image for slider. Every thing works good but look at the image below. When I click on button the animation starts and values on label change but the animation on slider directly jumps to 6 which you can see it and the same thing happens when the slider reaches it max value(100) from 96 the slider min image(orange color) disappears and the label continues to show values 97..98..99..100.
Here's the code snippet for reference :
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *sliderMinimum = [[UIImage imageNamed:#"slider_max"] stretchableImageWithLeftCapWidth:14 topCapHeight:0];
[self.slider setMinimumTrackImage:sliderMinimum forState:UIControlStateNormal];
UIImage *sliderMaximum = [[UIImage imageNamed:#"slider_min"] stretchableImageWithLeftCapWidth:14 topCapHeight:0];
[self.slider setMaximumTrackImage:sliderMaximum forState:UIControlStateNormal];
}
- (IBAction)btnClicked:(id)sender
{
[self.slider setValue:0 animated:true];
[self setSliderValue:2];
}
- (void)setSliderValue:(float)value
{
[UIView animateWithDuration:0.2 animations:^{
[self.slider setValue:value animated:true];
} completion:^(BOOL finished) {
self.lblSliderValue.text = [NSString stringWithFormat:#"%0.0f", self.slider.value];
if (self.slider.value != self.slider.maximumValue) {
[self setSliderValue:value+1];
}
}];
}

Try with this:
[slider addTarget:self
action:#selector(roundValue:)
forControlEvents:UIControlEventValueChanged];
And in the roundValue function set the value:
- (void)roundValue{
[slider setValue:((int)((slider.value + 0) / 1) * 1) animated:NO];
}

Related

iOS: Changing a UIImageView by pressing an UIButton

I'm making a very simple game. I have a UIButton and an UIImageView. What I'm trying to do is that when the user presses the button, it will change the image to another image and then back to the original image, to simulate an animation (Character moving)
I have this code:
file.m
{
IBOutlet UIImageView *image1;
IBOutlet UIButton *button;
}
-(IBAction)button:(id)sender;
file.h
-(IBAction)button:(id)sender{
[UIView animateWithDuration:1.0f
animations:^{
image1.alpha = 0.1f;
} completion:^(BOOL finished) {
image1.image = [UIImage imageNamed:#"image2.png"];
[UIView animateWithDuration:0.2f
animations:^{
image1.alpha = 1.0f;
} completion:^ (BOOL finished) {
image1.image = [UIImage imageNamed:#"image1.png"];
}];
}];
}
When I open the iOS simulator and press the button, the image dissolves, then reappears and then does the animation. The problem is that I don't want it to dissolve, I just want to show the animation. How do I prevent this from happening? Is it because I'm using alpha properties?
Thank you!
I used the following code to do what I think is what you need (shown here: https://www.dropbox.com/s/vtcyw0n257tgihx/fade.mov?dl=0):
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(test)];
iv = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 150, 150)];
iv.image = [UIImage imageNamed:#"red"];
[self.view addSubview:iv];
}
- (void)test {
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 0.0f;
} completion:^(BOOL finished) {
iv.image = [UIImage imageNamed:#"blue"];
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 1.0f;
} completion:^ (BOOL finished) {
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 0.0f;
} completion:^ (BOOL finished) {
iv.image = [UIImage imageNamed:#"red"];
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 1.0f;
} completion:nil];
}];
}];
}];
}
You need to break it down into four parts. First you need to fade the original image out, change it to the second image, fade the second image in, fade the second image out, change back to the original image, then fade it back in.

Show UIImageView on screen Tap

I am trying to Display a an Image when the user Taps on the UIImageView. But before the user Taps the UIImageView the Image should not be shown, and after a few seconds the Image should disappear again. Does anyone know how to do this? I read through couple of Threads but they do not work with the latest Xcode as it appears. Thanks for your help and time.
Udate
Well, my code now looks like this:
-(void)imageTapped:(UITapGestureRecognizer*)recognizer
{
recognizer.view.alpha=0.0;
((UIImageView*)recognizer.view).image = [UIImage imageNamed:#"twingo_main.png"];
[UIView animateWithDuration:1.0 delay:2.0 options:0 animations:^{
recognizer.view.alpha=1.0;
} completion:^(BOOL finished) {
recognizer.view.alpha=0.0;
((UIImageView*)recognizer.view).image = nil;
recognizer.view.alpha=1.0;
}];
}
- (void)viewDidLoad
{
UIImageView *hiddenImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 30, 20, 20)];
hiddenImage.userInteractionEnabled=YES;
[hiddenImage addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)]];
[self.view addSubview:hiddenImage];
Well, now my question is, how do I need to set up the UIImageView in the View Controller?
In your UIViewController's viewDidLoad method:
...
UIImageView *hiddenImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 30, 20, 20)];
hiddenImage.userInteractionEnabled=YES;
[hiddenImage addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)]];
[self.view addSubview:hiddenImage];
...
UITapGestureRecognizer Handler:
-(void)imageTapped:(UITapGestureRecognizer*)recognizer
{
recognizer.view.alpha=0.0;
((UIImageView*)recognizer.view).image = [UIImage imageNamed:#"imageName"];
[UIView animateWithDuration:1.0 delay:2.0 options:0 animations:^{
recognizer.view.alpha=1.0;
} completion:^(BOOL finished) {
recognizer.view.alpha=0.0;
((UIImageView*)recognizer.view).image = nil;
recognizer.view.alpha=1.0;
}];
}
Set the image in the UIImageView to nil initially. Add a tap gesture recognizer to the UIImageView that, when fired, sets the image and starts a timer. When the timer completes, set your image back to nil.
Here is an another way to handle above with NSTimer..
-(void)imageTapped:(UITapGestureRecognizer*)recognizer
{
CustomPopUpView *lCustomPopUpView = [[CustomPopUpView alloc]init];
//Added your imageview to Custom UIView class
[self.window addSubview:lCustomPopUpView];
[self.window bringSubviewToFront:lCustomPopUpView];
mPopupTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(closePopUp) userInfo:Nil repeats:FALSE];
}
- (void)closePopUp{
if (mPopupTimer != nil) {
[mPopupTimer invalidate];
mPopupTimer = nil;
}
for (UIView *lView in self.window.subviews) {
if ([lView isKindOfClass:[CustomPopUpView class]]) {
[lView removeFromSuperview];
}
}
}
Its better to have view behind the UIImageView to handle the TapGesture.
But here is the fix for you code:
Add this to viewDidLoad method to setup you image view to handle tap gesture
//By default the UserInteraction is disabled in UIImageView
[self.testImageView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapgesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(ShowImage:)];
tapgesture.numberOfTapsRequired=1;
tapgesture.numberOfTouchesRequired=1;
[self.testImageView addGestureRecognizer:tapgesture];
here is the method handle the gesture event
-(void)ShowImage:(UIGestureRecognizer*)recognizer{
recognizer.view.alpha=0.0;
((UIImageView*)recognizer.view).image = [UIImage imageNamed:#"clone.jpg"];
[UIView animateWithDuration:1.0 delay:0 options:0 animations:^{
recognizer.view.alpha=1.0;
} completion:^(BOOL finished) {
//[self performSelector:#selector(hideImage:) withObject:recognizer.view afterDelay:10];
[UIView animateWithDuration:1.0 delay:3.0 options:0 animations:^{
recognizer.view.alpha=0.0;
} completion:^(BOOL finished) {
((UIImageView*)recognizer.view).image=nil;
((UIImageView*)recognizer.view).alpha=1.0;
}];
}];
}
If you set the alpha of view to 0, then your view will not receive any touch event further. So its best practice to set it again to 1.0 after removed the image from UIImageView.
You may want to consider using a UIButton. Detecting touches with these is easy - as is changing their image.
You could also subclass UIControl (see http://www.raywenderlich.com/36288/how-to-make-a-custom-control).

View is not set back to original position

In my xib i have set one text box ...when user edit in it i am moving that view little up...but when i return back it to its original postion it not come to its original postion it remain little up then original postion.
Here is viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])self.edgesForExtendedLayout = UIRectEdgeNone;
search=FALSE;
UIButton *btnOther = [UIButton buttonWithType:UIButtonTypeSystem]; //UIButtonTypeCustom for image button
[btnOther setTitle:#"Save" forState:UIControlStateNormal];
btnOther.titleLabel.font = [UIFont fontWithName:GZFont size:12.0f];
// [btnSave setImage:[UIImage imageNamed:#"save.png"] forState:UIControlStateNormal];
[btnOther addTarget:self action:#selector(btnSaveAction:) forControlEvents:UIControlEventTouchUpInside];
[btnOther setFrame:CGRectMake(0, 0, 55, 29)];
dataArray=[[NSMutableArray alloc]init];
nameSearchArray=[[NSMutableArray alloc]init];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btnOther];
txtCharityName.hidden=YES;
txtCharityMail.hidden=YES;
originalCenter=self.view.center;
}
here is textfield delegate methods.:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField==txtGratuity){
self.view.center=CGPointMake(originalCenter.x, originalCenter.y-30);
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.view.center=CGPointMake(originalCenter.x, originalCenter.y);
charityId=#"";
NSLog(#"charityID%#",charityId);
}
and here is screenshot.:
as per this equation
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
you should add 30 points for textfield to get to correct position.
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.view.center=CGPointMake(originalCenter.x, originalCenter.y+30);
charityId=#"";
NSLog(#"charityID%#",charityId);
}
Edit:
try this in your
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:0.25
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame;
// let's move our textField
frame = textField.frame;
frame.origin.y = frame.origin.y-30;
textField.frame=frame;
}
completion:^(BOOL finished){
if(finished) NSLog(#"Finished !!!!!);
}];
}
and move textfield down after edit
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.25
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame;
// let's move our textField
frame = textField.frame;
frame.origin.y = frame.origin.y+30;
textField.frame=frame;
}
completion:^(BOOL finished){
if(finished) NSLog(#"Finished !!!!!);
}];
}
Set the textfield frames in viewWillAppear instead of viewDidLoad method.

Change Background Image and animate an UIButton when tapped iOS 7 [duplicate]

This question already has answers here:
Animating only the image in UIBarButtonItem
(4 answers)
Closed 8 years ago.
I have an UIButton created by the following code
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"refresh_icon.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"reload_selected.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 20 , 20)];
Here when it's clicked the selector buttonAction is called and I am animating the button by a 360 degree rotation like this
- (void) buttonAction : (id) sender {
NSLog(#"Reload Button Clicked");
[self runSpinAnimationOnView:self.button duration:1.0 rotations:1.0 repeat:0];
}
- (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration rotations:(CGFloat)rotations repeat:(float)repeat;
{
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = repeat;
[view.layer addAnimation:rotationAnimation forKey:#"rotationAnimation"];
}
It's working good but it's not that I actually want. I want that , when my button is clicked then button will take the image "reload_selected.png" (which I set for UIControlStateSelected) as background and then run the animation. When the animation is finished then button will have to return to it's actual background ("refresh_icon.png") again.
Can anyone suggest some change in code that will help me achieve the action I described above ? Thanks in advance for your help.
Can you try like this,
[UIView animateWithDuration:YOURDURATION
delay:0
options:(UIViewAnimationOptionCurveLinear)
animations:^ {
[button setImage:[UIImage imageNamed:#"reload_selected.png"] forState:UIControlStateSelected];
button.transform = CGAffineTransformRotate(CGAffineTransformIdentity,M_PI * 2);
}
completion:^(BOOL finished) {
[button setImage:[UIImage imageNamed:#"refresh_icon.png"] forState:UIControlStateNormal];
}
];
Instead of using Core Animation, you can use animateWithDuration:animations:completion: method of UIView. This method allows you to specify a completion block whick you can use to reset the image once the animation is completed.
EDIT:
Do something like
[view animateWithDuration:duration animations:^{
//Do your animations here
} completion: ^(BOOL finished){
if(finished) {
//reset the image
}
}];
To specify the animations you might want to animate the view's transform property using CGAffineTransformRotate.

How to create an animation by changing images after a certain amount of time

Hello guys I am new to xcode and I am trying to animate balloons on touch by changing its images: this is my code:
now the problem i am facing is its not animating images means the animation timer is not working: please guide me what should i do to animate the images with time: if I am not doing it properly then please guide me that how can i do it by NSTimer?
-(void)baloonbursting:(UIButton *)button withEvent:(UIEvent *)event{
if ([[UIImage imageNamed:#"redbaloons.png"] isEqual:button.currentImage]) {
NSLog(#"em redbaloons.png");
UIImage *bubbleImage3 = [UIImage imageNamed:#"redburst.png"];
[button setImage:bubbleImage3 forState:UIControlStateNormal];
}
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView animateWithDuration:1.0f animations:^(){
// define animation
if ([[UIImage imageNamed:#"redburst.png"] isEqual:button.currentImage]) {
NSLog(#"em redbaloons.png");
UIImage *bubbleImage3 = [UIImage imageNamed:#"redburst2.png"];
[button setImage:bubbleImage3 forState:UIControlStateNormal];
}
}
completion:^(BOOL finished){
// after the animation is completed call showAnimation again
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished){
if (finished) {
[button removeFromSuperview];
}}];
}];
}
I want you to give you a solution to show you the right direction to think. That is, why I developed a small test project in Xcode and I controlled that this code really works.
First: forget NSTimers for this animation!
The idea is, that you "play" around with subviews, because you can change their alpha properties from 0.0 (invisible) to 1.0 (fully opaque), which are supported by the SDK's view animations.
Please change the image names according to your own file names (I've used my own here).
The following method checks, if the button's image is that one that shall invoke an animation - exactly what you did before. If this condition is met, it visually animates the change of the button's image to another image:
- (IBAction)balloonBursting:(UIButton *)sender
{
BOOL doAnimate = NO;
UIImageView *ivOldBubbleImage;
UIImageView *ivNewBubbleImage;
if ([[UIImage imageNamed:#"BalloonYellow.png"] isEqual:sender.currentImage]) {
NSLog(#"will animate");
doAnimate = YES;
UIImage *newImage = [UIImage imageNamed:#"BalloonPurple.png"];
ivNewBubbleImage = [[UIImageView alloc] initWithImage:newImage];
ivNewBubbleImage.alpha = 0.0;
ivOldBubbleImage = sender.imageView;
[sender addSubview:ivNewBubbleImage];
}
if (doAnimate) {
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView animateWithDuration:1.0f animations:^(){
// define animation
ivOldBubbleImage.alpha = 0.0;
ivNewBubbleImage.alpha = 1.0;
}
completion:^(BOOL finished){
[sender setImage:ivNewBubbleImage.image forState:UIControlStateNormal];
[ivNewBubbleImage removeFromSuperview];
}];
}
}

Resources