I would like to animate a UIButton which is at the bottom of my UIView when the keyboard becomes/resigns first responder. Before iOS 7 I made a simple animation that moves the button, but now the animation of the keyboard is non linear, it starts faster and ends more slowly. I've been told to do it with the new UIKit Dynamics but don't have any idea of how can I achieve my goal. Any suggestion?
Thanks in advance.
Listen to keyboard notifications. There you can obtain the following information and animate your button accordingly.
UIKeyboardAnimationCurveUserInfoKey The key for an NSNumber object containing a UIViewAnimationCurve constant that defines how the
keyboard will be animated onto or off the screen.
Available in iOS 3.0 and later.
Declared in UIWindow.h.
UIKeyboardAnimationDurationUserInfoKey The key for an NSNumber object containing a double that identifies the duration of the
animation in seconds.
Available in iOS 3.0 and later.
Declared in UIWindow.h.
More information here:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/constant_group/Keyboard_Notification_User_Info_Keys
possible duplicate, another possible duplicate
#Leo: I've tried using those values but they didn't work for me (and others I've seen), so I ended up with this:
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:500.0f
initialSpringVelocity:0.0f
options:UIViewAnimationOptionCurveLinear
animations:animBlock
completion:completionBlock];
Related
On iOS 7, when you present a UIPopoverController, the system adds a UIView with some alpha effect to focus the user on the UIPopoverController. So far, so good.
The problem is that if you have a UIPopoverController that's being displayed from the bottom of your screen, and that UIPopoverController content has a UITextField (or anything else that brings the keyboard), the dimmed UIView animation doesn't follow the keyboard very well.
I've created a sample project to isolate the problem. Download Project
And a video of the same issue running on the simulator: Watch Movie
One solution could be to just disable the dimmed UIView as mentioned here, but I would like to keep it if possible.
Is there a workaround or maybe I'm doing something wrong?
I'm starting to consider to fill a bug for this.
Thanks.
Have you tried wrapping your code in a block to disable CoreAnimations implicit animation blocks? Something like this
[CATransaction begin];
[CATransaction setDisableActions: YES];
// Show your popover:
// [myPopover presentPopover:...]
[CATransaction commit];
I'm updating my iPhone app for the iPhone 5's larger screen, and there seems to be a problem with animateWithDuration:. Before I turned on autolayout, the interface elements would move slightly up the screen when the UITextField became first responder, and would move down back to their original positions when the UITextField lost its first responder status. Now, they just haphazardly fly up and off the screen, and I have no idea why. I move the objects with the code below (and this worked with autolayout turned off):
[UIView animateWithDuration:.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
int offset = 160;
[object1 setFrame:CGRectMake(0, -offset, object1.frame.size.width, object1.frame.size.height)];
[object2 setFrame:CGRectMake(object2.frame.origin.x, object2.frame.origin.y-offset, object2.frame.size.width, object2.frame.size.height)];
[object3 setFrame:CGRectMake(object3.frame.origin.x, object3.frame.origin.y-offset, object3.frame.size.width, object3.frame.size.height)];
}
completion:^(BOOL finished){}];
Does it have something to do with trying to move the objects by a constant? Even when I set offset to 0, all the objects still fly off the screen. I've tried detecting which screen the device has and moving the objects by different amounts, but that hasn't worked either. Does anybody have any ideas?
Thanks in advance!
When using auto layout, unless these are objects that were manually added to the view with translatesAutoresizingMaskIntoConstraints = YES, autolayout will often thwart attempts to animate by changing the frame. If there is anything in place that will cause the constraints to be reapplied, the objects will move back to wherever the constraints dictate they should be, overriding your attempts to adjust their frame properties.
If animating the movement of objects like this while using autolayout, you would either (a) create an IBOutlet for their top constraint (if adjusting y; if adjusting x, too, you would use the leading constraint also) and then change that constraint's constant property and then call layoutIfNeeded from within the animation block; or (b) remove the constraints and create new ones. (I generally do the former.)
See the latter part of this answer for an example of how to create IBOutlet for constraint and then changing the constant property in animation block.
I'm using two UITextView objects. Each UITextView represents the side of a single card in a flash card application. Just like when using regular flash cards, I want the user to have the ability to flip a card. I am asking how to flip between two UIView objects because UITextView are UIView subclasses so the same idea should work.
The animation I am looking for looks like this.
The only problem with the above example is that it utilizes two UIViewController objects and UITextView is not a subclass of UIViewController so the same principle does not apply.
Any ideas on how to do the flip animation?
You can use the UIView class method +transitionFromView:toView:duration:options:completion: to accomplish this. Both your text views need to be descendants of a common superview. Use the option UIViewAnimationOptionTransitionFlipFromLeft (or ...FromRight) to get a horizontal flip.
Looks like your question has been answered already here, just tweak the transform to make it a horizontal instead of vertical flip:
- (void)horizontalFlip {
[UIView animateWithDuration:someDuration animations:^{
yourView.layer.transform = CATransform3DMakeRotation(M_PI, 0.0, 1.0, 0.0);
} completion:^(BOOL finished){
// code to be executed when flip is completed
}];
}
As explained in that linked question, you can further modify this to do half the flip by using M_PI_2, then in the completion block of the first animation swap out the UITextViews and start a new animation to finish the flip.
Don't forget to #import math.h and #import <QuartzCore/Quartz.h> at the top of your file!
you can first hide the one UITextView and Show the another UITextView. To flip it, you can hide the displayed UITextView and show the hidden UITextView. You can also use animations explained here for it to create a flip effect.
This probably sounds harder than it is. I'm actually trying to chain some animations together to make it look smooth. What I'm doing is some basic animation of a UIPickerView that slides from the bottom of the screen and when it is dismissed it slides back to the bottom of the screen. I handle this functionality in two methods - (void)showPicker and - (void)hidePicker
Directly after the picker has been hidden I want to show the keyboard, but I don't want to show the keyboard before the picker has been hidden.
Also I want to this the other way around, directly after the keyboard has been hidden I want to show the UIPickerView. I know I can observe notifications of UIKeyboardDidShowNotification and UIKeyboardDidHideNotification
So what would be the best way to deal with this so that these animations are chained together in a smooth way?
For the path picker->keyboard try
[UIView animateWithDuration:0.3
animations:^{
[self hidePicker];
}
completion:^(BOOL finished){
[yourInputView becomeFirstResponder];
}];
The other way around listen to UIKeyboardDidHideNotification and invoke showPicker in the callback.
Do you show your picker as a way to input some info in a field or something?
If so, you better use the inputView property of UITextField so that it behaves quite like a normal TextField but uses your UIPickerView instead of the standard keyboard.
That's the standard way to do this (showing a picker in place of the keyboard) and you won't have to bother about chaining animations.
I'm writing an app where one component is a checklist screen. The checklist has 4 or 5 logical subsections and I want to display each section as a separate view, with the user switching between views with forward and back buttons (and eventually with a swiping gesture event but that's a separate issue).
Currently, I have a UIViewController class for managing the checklist logic, which loads the initial view from a xib. The xib contains all of the 4 or 5 views, and I can currently fairly easily switch between them just by setting up references to all the UIView objects in the UIViewController and calling
[self setView:viewNumberX];
within that class. However, this just abruptly switches the view, and doesn't have the nice iOS-style animation.
The reason I did it this was was because I thought the proper paradigm was to have one UIViewController managing one or several distinct related views - in this case, my one UIViewController is managing all 4 or 5 subviews because they are all parts of the same checklist subject to the same checklist logic. I do notice that there's a presentModalViewController:(UIViewController*)animated:BOOL method defined for UIViewControllers that does allow me the option of animating as I switch views, but this seems to require that I wrap my UIViews in 4 or 5 separate UIViewControllers, which doesn't make sense to me. The individual views don't have their own logic. Is there another way to get this functionality, or am I approaching this the wrong way?
If you are set about not having a UIViewController for each UIView, you can fix the animation bit using beginAnimations:context: and commitAnimations. Basically you use them like this, e.g.:
[UIView beginAnimations:#"animationName" context:nil];
[UIView setAnimationDuration:0.80];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.navigationController.view cache:NO];
...<change view>...
[UIView commitAnimations];
Actually, if you are targeting iOS 4, you are required to use animateWithDuration:animations:, but the concept remains the same. Here you will find a code snippet to do the flip with the latter.
If you want to have checklists you can swipe through, you can avoid both gestures and animations by using UIScrollView with pagingEnabled set to YES. Make the scroll view as wide as screen, and make it's contentSize property as wide as screen * number of screens, then place each checklist inside that scrollview with x coordinate being something like padding + PageNumber * 320 (with pageNumber being an int and starting with 0). If you chose this approach I'm here if you need more details or sample code.