UIView Animaton Resets to beginning - iphone

I'm attempting to run an animation so that the scrollview's contentoffset gets continually scrolling down.
However, after each repeat, it will animate from the original position and it is not progressing.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationRepeatCount: 100];
CGPoint contentOffset = scrollView.contentOffset;
contentOffset.y += 50;
scrollView.contentOffset = contentOffset;
scrollView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
any ideas ?

Why are you attempting to manually scroll the view? Can't you use the method
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
?
Regardless, I believe the reason your animation isn't working as you expect is because you're setting a repeat count instead of actually re-rendering your animation each time. If you want to work around this problem, you could animate again in the animation callback by creating a method wrapping the animation and passing parameters via the context pointer.
- (void) animateContentOffsetByAmount:(CGFloat)amount numberRemaining:(int)num {
if (num == 0) return;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:
#selector(scrollAnimationStoppedWithID:finished:context:)];
//NSArray released in callback
NSArray* contextArray = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:amount],
[NSNumber numberwithInt:num], nil]
[UIView beginAnimations:nil context:contextArray];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
CGPoint contentOffset = scrollView.contentOffset;
contentOffset.y += amount;
scrollView.contentOffset = contentOffset;
scrollView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
}
- (void) scrollAnimationStoppedWithID:(NSString*)id
finished:(NSNumber*)finished context:(void*)context {
NSArray* contextArray = (NSArray*)context;
CGFloat amount = [(NSNumber*)[contextArray objectAtIndex:0] floatValue];
int count = [(NSNumber*)[contextArray objectAtIndex:1] intValue];
count = count - 1;
[contextArray release];
[self animateContentOffsetByAmount:amount numberRemaining:count]
}
Then in your code, just call
[self animateContentOffsetByAmount:50 numberRemaining:100];

Related

UIButton actions

I have a UIButton set up in a storyboard that when pressed animates a UIVIew. I would like the same button to animate/move the UIView back to it's original point when it is pressed a second time.
What is the best way to do this?
thanks for any help or pointers.
this is the code I'm using to animate and move the UIVIew:
I'm using a BOOL named buttonCurrentStatus.
-(IBAction)sortDeals:(UIButton*)sender {
if (buttonCurrentStatus == NO)
{
buttonCurrentStatus = YES;
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = yes");
} else {
buttonCurrentStatus = NO;
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = no");
}
Another more general way is to use an IBAction that will execute one of two methods. Like previous answers, you can use a BOOl value, or int in order to determine what action to use. This is a more general answer, and can be used for many purposes.
First, you will need a BOOL variable. For this example I put the Bool variable as boolVarible (Yes, I know I spelled it wrong). By default I have it set to YES.
bool boolVarible = YES;
I made that a class variable.
-(IBAction)buttonAction:(id)sender {
if (boolVarible == YES)
{
//Execute first action
[self firstAction];
}
else
{
//Execute second action
[self secondAction];
}
}
-(void)firstAction {
//Do something here...
}
-(void)secondAction {
//Do something here...
}
Hopefully, you get the idea. You can then swap actions whenever you want. Just simply change the BOOl value, and then when the button is pressed, it will execute another method. I find this cleaner than doing it all in one action. Good luck.
-(IBAction)sortDeals:(UIButton*)sender {
sender.selected = !sender.selected;
int moveby = (sender.selected) ? 30: -30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
menuTop.frame = CGRectMake(menuTop.frame.origin.x, menuTop.frame.origin.y + moveby, menuTop.frame.size.width, menuTop.frame.size.height);
[UIView commitAnimations];
}
Very Simply Solution for your Question is if you Declare two Boolean Variables in Class where you need to implement this method.your Code will be look like this
In .m file
BOOL Action1;
BOOL Action2;
Now In ViewDidload method
(void)viewDidLoad
{
Action1=TRUE;
Action2=FALSE;
[super viewDidLoad];
}
And now your Method
(IBAction)sortDeals:(UIButton*)sender {
if (Action1 == TRUE)
{
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = yes");
Action1=FALSE;
Action2=TRUE;
}
else
if (Action2 == TRUE)
{
CGRect menuTopFrame = self.menuTop.frame;
menuTopFrame.origin.y = 30;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.menuTop.frame = menuTopFrame;
[UIView commitAnimations];
NSLog(#"Sort Deals touched button status = no");
Action1=TRUE;
Action2=FALSE;
}
Hope it Works for you.Thanks

UIView animation for CGAffineTransformMake not working

I have a simple transform animation that moves a UITableViewCell 70 pixels to the left. In the if part, the animation works just fine and I get a smooth transition. However, when the function is called again to put the cell back in its original position, which is the else part, I get no animation. It just returns back to normal but without animation. How can I fix this?
if([[slideArray objectAtIndex:indexPath.row] intValue]==0)
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(-70, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:1]];
}
else
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
}
try the following animation in else condition this will work fine if you alreadyb have perform translation of if condition....
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(70, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
if above code not working for you than try the following
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
myImageView.transform=CGAffineTransformMakeTranslation(-70, 0);
}
completion:^(BOOL finished){
myImageView.transform=CGAffineTransformIdentity;
}];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
let me know if any issues ..
regards.

How to animate a UITextView that is a subview?

I am trying to animate a UITextView (myTextView) that is a subview inside a UIScrollView (scrollView).
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:myTextView cache:YES];
[scrollView addSubview:myTextView];
[UIView commitAnimations];
myTextView appears without animation!
What kind of animation do you want to do? If you want to fade in, for example, you have to do
[scrollView addSubview:myTextView];
myTextView.alpha = 0.0;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:myTextView cache:YES];
myTextView.alpha = 1.0;
[UIView commitAnimations];
You can change several properties (e.g.: frame, transform) to make animations.
http://www.4shared.com/dir/-PGqZEXR/zoominzoomout.html just add this file with your project and call it through this functions
here im2 is UIVIEW and i paste image on it then passing this through view didload like this
- (void)viewDidLoad {
[self loadFlowersInView:im2];
[self.view addSubview:im2];
}
now attach this function like this
- (void) loadFlowersInView: (UIView *) backdrop {
NSString *create_button = nil; // Add the flowers to random points on the screen
for (int i = 0; i < 1; i++) {
MagPicAppDelegate *appdelegate = (MagPicAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *whichFlower = appdelegate.imageName;
UIImage *stemp = [UIImage imageNamed:#"approve.png"];
DragView *dragger = [[DragView alloc] initWithImage:stemp];
dragger.userInteractionEnabled = YES;
dragger.center = CGPointMake(160.0f, 140.0f);
[im2 addSubview:dragger];
[dragger release];
}
[self.view addSubview:im2];
[im2 release];
}

Spawning infinite UIImageViews without name collisions

iPad app. OS 4.2.
I have a button that, when pressed, calls this function that creates a UIImageView and animates it (and calls a second animation block). I created another button that calls the same function and passes different locations and different URL to a graphic.
I'm starting to get glitches—the first graphic spawned from the first button has the locations passed from the second button. This is probably due to the fact that I am not dynamically naming the UIImageView and getting collisions from that.
So how do I dynamically create and name any infinite number of UIImageViews? Especially since, to reference the UIImageView in two functions, it needs to be declared outside of the functions.
-(void)makeSoundEffectWordAppear:(NSString *)imageName:(int)startingX:(int)startingY:(int)endingX:(int)endingY{
myImage = [UIImage imageNamed:imageName];
[testWord setImage:myImage];
testWord = [[[UIImageView alloc] initWithFrame:CGRectMake(startingX,startingY,myImage.size.width,myImage.size.height)] autorelease];
[self.view addSubview:testWord];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView beginAnimations:#"moveWord" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeWord:finished:context:)];
//[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationBeginsFromCurrentState:YES];
testWord.transform = CGAffineTransformMakeScale(1, 1);
testWord.center = CGPointMake(endingX,endingY);
testWord.alpha=1;
[UIView commitAnimations];
}
- (void)fadeWord:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
[UIView beginAnimations:#"makeWordFade" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDelay:5];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView setAnimationDuration:1];
[UIView commitAnimations];
}
You have a single pointer to testWord rather than a pointer for each instance. You should be using the context property of animations to pass in the specific UIImageView you want to fade away:
-(void)makeSoundEffectWordAppear:(NSString *)imageName:(int)startingX:(int)startingY:(int)endingX:(int)endingY{
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *testWord = [[[UIImageView alloc] initWithImage:myImage] autorelease];
CGRect frame = [testWord frame];
frame.origin.x = startingX;
frame.origin.y = startingY;
[testWord setFrame:frame];
[self.view addSubview:testWord];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView beginAnimations:#"moveWord" context:testWord];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeWord:finished:context:)];
//[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationBeginsFromCurrentState:YES];
testWord.transform = CGAffineTransformMakeScale(1, 1);
testWord.center = CGPointMake(endingX,endingY);
testWord.alpha=1;
[UIView commitAnimations];
}
- (void)fadeWord:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
UIImageView *testWord = (UIImageView *)context;
[UIView beginAnimations:#"makeWordFade" context:context];
[UIView setAnimationDelegate:self];
[UIView setAnimationDelay:5];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView setAnimationDuration:1];
[UIView commitAnimations];
}

How can I present a UIView from the bottom of the screen like a UIActionSheet?

I'd like a UIView to slide up from the bottom of the screen (and stay mid-screen) like a UIActionSheet. How can I accomplish this?
UPDATE:
I am using the following code:
TestView* test = [[TestView alloc] initWithNibName:#"TestView" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
test.view.center = CGPointMake(160,100);
//test.view.frame = CGRectMake(0, 0, 160, 210);
[[[UIApplication sharedApplication] keyWindow] addSubview:test.view];
[UIView commitAnimations];
The view seems to be animating from the corner and appearing in the corner. How can I make it slide up from the bottom? Getting close!
Do what Matt did here, but just change the values and direction. I have code at home to do this from the bottom if you need it later (I'll update this post).
Link: http://cocoawithlove.com/2009/05/intercepting-status-bar-touches-on.html
Also, don't forget to take out the bit of code that shifts the main view downward (so instead the UIView just pops over top like an ActionSheet)
Updated with code:
This is what I use in one of my apps to show/hide a little "options" view:
- (void)toggleOptions:(BOOL)ViewHidden
{
// this method opens/closes the player options view (which sets repeat interval, repeat & delay on/off)
if (ViewHidden == NO)
{
// delay and move view out of superview
CGRect optionsFrame = optionsController.view.frame;
[UIView beginAnimations:nil context:nil];
optionsFrame.origin.y += optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[UIView commitAnimations];
[optionsController.view
performSelector:#selector(removeFromSuperview)
withObject:nil
afterDelay:0.5];
[optionsController
performSelector:#selector(release)
withObject:nil
afterDelay:0.5];
optionsController = nil;
}
else
{
optionsController = [[PlayOptionsViewController alloc] init];
//
// Position the options at bottom of screen
//
CGRect optionsFrame = optionsController.view.frame;
optionsFrame.origin.x = 0;
optionsFrame.size.width = 320;
optionsFrame.origin.y = 423;
//
// For the animation, move the view up by its own height.
//
optionsFrame.origin.y += optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[window addSubview:optionsController.view];
[UIView beginAnimations:nil context:nil];
optionsFrame.origin.y -= optionsFrame.size.height;
optionsController.view.frame = optionsFrame;
[UIView commitAnimations];
}
}
One way would be to use the present modal view controller on the view controller:
presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
For more info take a look at the UIViewController documentation.
EDIT: If you want a mid-screen view you'll need to animate it into position as #jtbandes has pointed out. I suggest also adding some candy to UIView animation block:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myView.center = CGPointMake(x,y);
[UIView commitAnimations];
You can then move it again if you need to go full screen or dismiss it.
You'll have to move the view yourself, by setting its center or frame. I'll let you figure out what to set those to. But for the animation:
// set the view to its initial position here...
[UIView beginAnimations:nil context:NULL];
// move the view into place here...
[UIView commitAnimations];
Check out this post: http://blog.yetanotherjosh.com/post/33685102199/3-ways-to-do-a-vertical-transition-with
I'm going with the modal window approach.
Try this solution.... it works
#pragma mark - Date Selector View PresentModelView with Transparent ViewController
- (void) showModal:(UIView*) modalView {
CGRect rect=modalView.frame;
rect.origin=CGPointMake(0, 0);
self.tutorialView.frame=rect;
UIWindow *mainWindow = [(AppDelegate *)[UIApplication sharedApplication].delegate window];
CGPoint middleCenter;
middleCenter = CGPointMake(modalView.center.x, modalView.center.y);
CGSize offSize = [UIScreen mainScreen].bounds.size;
CGPoint offScreenCenter = CGPointMake(offSize.width / 2.0, offSize.height * 1.5);
modalView.center = offScreenCenter;
if ([[mainWindow subviews] containsObject:modalView]) {
[modalView removeFromSuperview];
}
[mainWindow addSubview:modalView];
[mainWindow bringSubviewToFront:modalView];
// Show it with a transition effect
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
// animation duration in seconds
modalView.center = middleCenter;
[UIView commitAnimations];
}
// Use this to slide the semi-modal view back down.
- (void) hideModal:(UIView*) modalView {
CGSize offSize = [UIScreen mainScreen].bounds.size;
CGPoint offScreenCenter = CGPointMake(offSize.width / 2.0, offSize.height * 1.5);
[UIView beginAnimations:nil context:(__bridge void *)(modalView)];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(hideModalEnded:finished:context:)];
modalView.center = offScreenCenter;
[UIView commitAnimations];
}
- (void) hideModalEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
UIView *modalView = (__bridge UIView *)context;
[modalView removeFromSuperview];
}