i´ve built a nested scroll view. in the view.xib there is in the view one scrollview with vertical scrolling named rootScroll. in this one there are two other scrollviews with horizontal scrolling named topScroll and bottomScroll.
my goal is to fade out bottomScroll when user drags the topScroll and fade it in again when decelerating ends.
the code workes fine so far. the only problem is that scrollViewWillBeginDragging gets messages from all three UIScrollViews. i´ve logged the sender and can see that they´re different but anyway i don´t know how to restrict the animation only to messages sent by the topScroll!
how can i distinguish different senders inside of scrollViewWillBeginDragging?
probably an objective-c absolute beginners question. i hope someone will give me a hint anyway.
thank you!
- (void)viewDidLoad {
[super viewDidLoad];
// rootScroll
[rootScroll setScrollEnabled:YES];
[rootScroll setContentSize:CGSizeMake(1024, 1980)];
// topScroll
[topScroll setScrollEnabled:YES];
[topScroll setContentSize:CGSizeMake(3072, 406)];
// bottomScroll
[bottomScroll setScrollEnabled:YES];
[bottomScroll setContentSize:CGSizeMake(3072, 188)];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)sender
{
NSLog(#"will begin dragging, %i", sender);
[UIScrollView beginAnimations:nil context:nil];
[UIScrollView setAnimationDuration:0.15f];
[self.bottomScroll setAlpha:0.0];
[UIScrollView commitAnimations];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender
{
NSLog(#"end position");
[UIScrollView beginAnimations:nil context:nil];
[UIScrollView setAnimationDuration:1.5f];
[self.bottomScroll setAlpha:1.0];
[UIScrollView commitAnimations];
}
Set the tag propeties of the scrollviews in Interface Builder. You can then use [sender tag] in your method to tell them apart.
Related
OKay I have been working on this problem for a while now, And It is well beyond my expertise thus why I am asking for help again.
I am trying to animate the transition for a tabbarbutton click to another view. I have declared in both viewController (ViewWillAppear) methods the code below
- (void)viewWillAppear:(BOOL)animated
{
//TODO: Fix transition animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.view cache:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView commitAnimations];
[super viewWillAppear:animated];
}
FirstViewController to the right and SecondViewController to the left.
Now the problem is happening when the user loads the app for the first time, once everything loads up and the user clicks on the tabbarbutton to go to the second view, it dose not flip.. but when you go back to the FirstView it animates then if you go to the second again it will animate this time round.. Dose anyone have any idea why this is happeneing? if you do your help would be greatly appreciated!
UPDATE::
I am trying to add a animation into viewDidLoad, however there is already an animation for an opening sequence I am loading straight away.
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//-- Start Opening Animation ------->
CGRect vaultTopFrame = vaultTop.frame;
vaultTopFrame.origin.y = -vaultTopFrame.size.height;
CGRect vaultBottomFrame = vaultBottom.frame;
vaultBottomFrame.origin.y = self.view.bounds.size.height;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.5];
[UIView setAnimationDelay:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
vaultTop.frame = vaultTopFrame;
vaultBottom.frame = vaultBottomFrame;
[self.view bringSubviewToFront:vaultTop]; //this should place this subview above any others on the same page
[self.view bringSubviewToFront:vaultBottom]; //this should place this subview above any others on the same page
[UIView commitAnimations];
I think this might be messing things up for me what do you think?
You do not have animation when the app loads up. Set animation in viewDidLoad for animation when the view loads up and viewDidAppear will give you animations when the user makes transition after wards (every time the tab is clicked).
This may or may not be the problem, but you should call
[super viewWillAppear:animated];
at the beginning of the method, before your animation code.
I have 2 subviews on the stage (a splash screen, and the main screen) once the splash screen finishes playing its audio it calls a function called -(void)audioComplete which is suppose to fade out the splash screen, revealing the main screen. I can't seem to get that working.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:splashController.view];
[self.window addSubview:rootController.view];
[self.window makeKeyAndVisible];
return YES;
}
-(void)audioComplete{
NSLog(#"REMOVE FROM STAGE");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:splashController.view];
splashController.view.alpha = 0.0;
[UIView commitAnimations];
[splashController release];
}
If I add NSLog(#"%#",[splashController.view superview]); in the audioComplete function I get (null), but not when I add it to the didFinishLaunchingWithOptions function.
Apple highly recommends against using splash screens. Instead, you should use an image called 'Default.png' in the root directory. This will get displayed while the application is launching and make it appear that your application is faster than it actually is. Apple could potentially reject your submission to the app store if you create your own loading screen.
Could be one of two things:
1) Seems like your rootControllerView is being added on top of the splashControllerView.
Maybe your animation is happening but you can't see it as your rootControllerView is blocking it.
Try reversing your order of addSubview.
2) Don't release your splash view in the same method you're using for animation. Wait for the animation to finish before releasing your view. You can do this by:
-(void)audioComplete
{
NSLog(#"REMOVE FROM STAGE");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidFinishSelector:#selector(releaseView)];
splashController.view.alpha = 0.0;
[UIView commitAnimations];
}
-(void)releaseView
{
[splashController release];
}
Also, as a best practice for memory management, don't release splashControllerView directly.
What I do is release a view immediately after adding it as a subview (adding a subview increases it's retain count).
When I'm done with the subview, I simply call [subView removeFromSuperView] which reduces the retain count and makes it zero.
Simply put:
UIView *view = [[UIView alloc] init]; //retain count = 1
[self.view addSubview:view]; //retain count = 2
[view release]; //retain count = 1
//do stuff with the view
[view removeFromSuperview]; //retain count = 0;
I don't really see your question, because in your didFinishLaunchingWithOptions you're adding your view and it's really there! So you will receive an answer every time you call NSLog(#"%#",[splashController.view superview]); but in audioComplete you release your subView and it's away... After this you can't get access to the superview, because - you're subView is released...
I would use this:
-(void)audioComplete{
NSLog(#"REMOVE FROM STAGE");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:splashController.view];
splashController.view.alpha = 0.0;
[UIView commitAnimations];
[splashController.view removeFromSuperview];
}
You'll get the same thing again, but you're subView is still there if you need something later.
For Fade in and Fade out images between splash and mainscreen. i suggest you could trying having two image in rootviewcontroller. made the fade in and fadeout animation between two UIIMageViews......
for fade in read out this sample tuts:
http://iosdevelopertips.com/user-interface/fade-transition-fade-images-in-and-out.html
during the animation, u can complete your audio streams
so, basically I need to know if there is a way to have a observer o another method that is called when the keyboard is hidden.
The problem i have is that after dismissing the Keyboard, I commit 2 Animations, one to take the view to the original position (since I move up the view so the user can see the textfield while typing) and an Animation Flipping the View but the Flip occurs before the Keyboard is fully hidden so I have a little graphic glitch.
I've tried sleep(), and another wait methods without luck.
The Code Basically is this
- (BOOL)textFieldShouldReturn:(UITextField *)textFieldi{
[textFieldi resignFirstResponder];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
CuantoFaltaiOSAppDelegate * del = [CuantoFaltaiOSAppDelegate instance];
del.headerView.frame = CGRectMake(0, 20, del.headerView.frame.size.width, del.headerView.frame.size.height);
[UIView commitAnimations];
return YES;
}
The problem is that the Keyboard isn't fully Hide and the Flip is perfomed, so i need a way to wait for it.
Register for the UIKeyboardDidHideNotification notification.
[[NSNotificationCenter defaultCenter] addObserver:(id)
selector:(SEL)
name:(NSString *)
object:(id)];
Example:
Subscribe to the UIKeyboardDidHideNotification as follows (put this in your viewWillAppear: method):
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
This assumes you have a method called keyboardDidHide: (this is where your animation logic will reside)
I am displaying a ticker at the bottom of a view (think of a news channel's headlines ticker bar) in the form of a horizontal scrollview. It works correctly when I set the repeatCount to infinite but I want to be able to do some other functionality when the animation starts and stops instead. However, after reading the documentation and many examples online, I can't get setAnimationWillStartSelector/setAnimationDidStopSelector to respond.
Here's my code:
- (void)animateView {
[UIScrollView setAnimationDelegate:self];
[UIScrollView setAnimationWillStartSelector:#selector(animationStart:context:)];
[UIScrollView setAnimationDidStopSelector:#selector(animationStop:finished:context:)];
[UIScrollView beginAnimations:#"pan" context:nil];
[UIScrollView setAnimationDuration:10.0f];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIScrollView setAnimationCurve:UIViewAnimationCurveLinear];
tickerScrollView.contentOffset = CGPointMake(textLabelRect.size.width,0);
[UIScrollView commitAnimations];
}
- (void)animationStart:(NSString *)animationID context:(void *)context {
NSLog(#"animationWillStart");
}
- (void)animationStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context {
NSLog(#"animationDidStop");
[self animateView];
}
At the moment this code is in my UIViewController subclass. However, I have also tried putting it all in my app delegate as well, whilst also changing the setAnimationDelegate obviously. I've tried using various animationDurations, repeatCounts, etc but still no luck.
Would really appreciate any help. Thanks
You can try putting the setAnimationDelegate, setAnimationWillStartSelector and setAnimationDidStopSelector inside the animation block. According to the iPhone OS Reference Library documentation, these methods have to be put inside the animation block in order for it to work.
Hope this helps!
aobs
I tried to add a animation to viewDidLoad and viewDidAppear, but it doesn't work:
- (void)viewDidAppear:(BOOL)animated{
[UIView beginAnimations:#"transition" context:NULL];
[UIView setAnimationTransition:110 forView:self.view cache:YES];
[UIView commitAnimations];
}
Why?
I had the same problem and I think I found the solution on this SO question.
When viewDidAppear gets called you still don't see anything on the screen (despite the name), but you are about to. You can then use a performSelector:withDelay or an NSTimer to launch your animation. The delay can just be 0.1 and your animation will play just when the screen appears.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"View did appear!");
[self performSelector:#selector(animationCode) withObject:nil afterDelay:0.1f];
}
- (void)animationCode {
// you animation code
}
You are not telling the view which state it should animate to so it won't do anything. You need to place code between beginAnimations:context: and commitAnimations that changes the appearance of the view (e.g. by removing one subview and adding another).
You're not using beginAnimations: and commitAnimations correctly. You're supposed to put something in between them that normally wouldn't be animated: e.g. with self.view.alpha = 0.5 you get a fading effect. They have no effect on anything that isn't between them.
By the time viewDidAppear: is called, your view, well... has appeared. It's too late to animate anything. What you actually want to do is something like this:
- (void)showMyViewWithAnimation {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:110 forView:childView cache:YES];
[parentView addSubview:childView];
[UIView commitAnimations];
}
In the example above, childView is what in your example is called self.view.
Please write out the name of the transition; no one knows what 110 is by looking at it. It's bad style. </pedantry>