Wait for Keyboard to Hide - iphone

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)

Related

Running code just before keyboard animation

I have a search bar in my app in which I would like some animation to occur just before the keyboard shows up when the focus is placed in the search box. Is there a delegate method I can make use of to intercept before the keyboard is shown?
I am currently running the following code to detect when the UISearchBar has been activated:
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
NSLog(#"Begin Editing");
CGRect newFrame = searchBar.frame;
newFrame.origin.y = 0;
[UIView animateWithDuration:0.25
animations:^{
searchBar.frame = newFrame;
[searchBar layoutSubviews];
}
completion:^(BOOL finished){
NSLog(#"Done!");
}
];
}
Can I delay the showing of the keyboard in anyway? Maybe call a halt to it and then show it in the completion handler?
you need to add an notification center to you code.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
then declare a method named keyboardDidShow: and add the animation code to it.
there many options available. I guess
name:UIKeyboardWillShowNotification
is also available. just check it if its there and it should work.
Cheers happy coding.!!
Yes, there is also searchBarShouldBeginEditing:. You can do your animations, then return YES.

how to restrict scrollViewWillBeginDragging to only one sender object?

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.

trying to remove a subview

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

How can I speed up this view transition, the first time through, on 3G phones?

The following function is a method of a class called TitleOverlay - which is a transparent overlay with a textView.
The function shows the overlay by animating its alpha, and in parallel uses the animationWillStart property of the animation to show the keyboard.
On 3G phones, the first time this function is called, there is some lag before the keyboard shows. In fact, I think the animation to show the overlay and show the keyboard are being serialized. I tried setting the length of the overlay alpha animation to various lengths, and the keyboad always shows after the animation completes.
Basically, the first time, there is lag. On all subsequent times, the keyboard and the overlay animations occur in parallel, and it looks nice.
WHat can I do to fix this?
- (void) showOverlay {
[[self superview] bringSubviewToFront:self];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[nc addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[UIView beginAnimations:nil context: nil];
[UIView setAnimationDuration: .5];
[UIView setAnimationDelegate:titleField];
[UIView setAnimationWillStartSelector:#selector(becomeFirstResponder)];
self.whiteBlock.alpha = 1;
[UIView commitAnimations];
}
The lag when displaying a keyboard for the first time in an iPhone application is a known issue. There is a hack to work around this, as pointed out in that question.

How to add an animation to the UIView in viewDidAppear?

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>