Animating a sub layer during focus change - objective-c

Xcode 8 beta 6, tvOS Beta 6
I have a tvOS app where I want to animate a background of a control when it gets or looses focus. I have set the control to have 'Custom' focus and implemented didUpdateFocusInContext:withAnimationCoordinator: on the control. Here's the code:
-(void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
// Create the layer if we don't have it.
if (!self->_focusLayer) {
// ... Create a new CALayer and store it in _focusLayer
}
// Animate in or out.
if (context.nextFocusedView == self) {
if (! self->_focusLayer.superlayer) {
STLog(self, #"Adding focus");
self->_focusLayer.opacity = 0.0f;
[self.layer addSublayer:self->_focusLayer];
[coordinator addCoordinatedAnimations:^{
self->_focusLayer.opacity = 1.0f;
}
completion:NULL];
}
} else {
if (self->_focusLayer.superlayer) {
STLog(self, #"Removing focus");
[coordinator addCoordinatedAnimations:^{
self->_focusLayer.opacity = 0.0f;
}
completion:^{
[self->_focusLayer removeFromSuperlayer];
}];
}
}
}
Everything works except the animation of the opacity of the sub layer.
I've searched the net and all the examples I've found indicate to me this should work. I've also tried switching to using a CABasicAnimation with no luck.
Anyone know why this is not working?

The focus coordinator is not an animation block itself. It just coordinates various animations to happen simultaneously. Since an opacity change is not an animation itself, you need to do your opacity or alpha changes within a UIView Animation block to make it an animation, which you add to the coordinator.
Try this:
-(void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
// Create the layer if we don't have it.
if (!self->_focusLayer) {
// ... Create a new CALayer and store it in _focusLayer
}
// Animate in or out.
if (context.nextFocusedView == self) {
if (! self->_focusLayer.superlayer) {
STLog(self, #"Adding focus");
self->_focusLayer.opacity = 0.0f;
[self.layer addSublayer:self->_focusLayer];
[coordinator addCoordinatedAnimations:^{
[UIView animateWithDuration: 0.4 animations:^{
self->_focusLayer.opacity = 1.0f;
} completion:NULL];
} completion:NULL];
}
} else {
if (self->_focusLayer.superlayer) {
STLog(self, #"Removing focus");
[coordinator addCoordinatedAnimations:^{
[UIView animateWithDuration:0.4 animations:^{
self->_focusLayer.opacity = 0.0f;
} completion:NULL];
} completion:^{
[self->_focusLayer removeFromSuperlayer];
}];
}
}
}
Please note that the above code is typed here and not tested in a project.
Also note that the Animation duration is ignored by the animation coordinator and the default focus animation duration is used, unless you set an animation option to override inherited durations using:
options:UIViewAnimationOptionOverrideInheritedDuration
More about managing the focus animation coordinator here:
https://developer.apple.com/reference/uikit/uifocusanimationcoordinator

Related

IOS8 how to move an active popover

I have developed an app for iOS7 and now trying to update it for iOS8.
Issue i have is the following:
The app screen orientation can be rotated and a few buttons in some cases move drastically. I have a few popovers that point to these buttons, so if a popover is open when screen rotates, button moves, i need the popover to also.
In iOS7 i did this by the following:
When screen rotated i updated the constraints
- (void) updateViewConstraints
{
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.Button.constant = (CGFloat)10;
}
else
{
self.Button.constant = (CGFloat)5;
}
[super updateViewConstraints];
}
I also move the popover
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
if(TempDisplayPopoverController == examplePopoverController)
{
[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
I initially load the popover
- (void) LoadPopover{
examplePopover = [[examplep alloc] initWithNibName:#"exampleP" bundle:nil];
[examplePopover setDelegate:self];
examplePopoverController = [[UIPopoverController alloc] initWithContentViewController: examplePopover];
[examplePopoverController setDelegate:self];
examplePopoverController.popoverContentSize = examplePopover.view.frame.size;
TempDisplayPopoverController = examplePopoverController;
if ([examplePopoverController isPopoverVisible])
{
[examplePopoverController dismissPopoverAnimated:YES];
}
else
{
[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
[self ExamplePopoverPosition] just returns button position.
This all worked fine, i was happy, iPad was happy and all behaved.
Now due to iOS8 i have to change a few bits.
self.interfaceOrientation is depreciated
[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
in didRotateFromInterfaceOrientation throws an error
"Application tried to represent an active popover presentation: <UIPopoverPresentationController: 0x7bf59280>"
I've managed to rectify self.interfaceOrientation by
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self SetUpScreen:toInterfaceOrientation];
}
- (void) SetUpScreen:(UIInterfaceOrientation)toInterfaceOrientation{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.Button.constant = (CGFloat)10;
}
else
{
self.Button.constant = (CGFloat)5;
}
[super updateViewConstraints];
}
but have no idea how to resolve the popover issue. I have tried
popoverController: willRepositionPopoverToRect: inView:
but just can't to seem to get it to work.
Can anyone advice
Thanks
In iOS 8 you can use -viewWillTransitionToSize:withTransitionCoordinator: to handle screen size (and orientation) changes:
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[_popover dismissPopoverAnimated:NO];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Update your layout for the new size, if necessary.
// Compare size.width and size.height to see if you're in landscape or portrait.
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[_popover presentPopoverFromRect:[self popoverFrame]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:NO];
}];
}
When you implement this method, the deprecated rotation methods like willAnimateRotationToInterfaceOrientation: will not be called when running on iOS 8.
When using popoverController:willRepositionPopoverToRect:inView:, when reassigning to the rect parameter, try using:
*rect = myNewRect;
and not:
rect = &presentingRect;
Also, make sure you have properly assigned the popover controller's delegate.
First, you don't need to dismiss and present the popover on rotation. UIPopoverPresentationController does that for you. You don't even need to update sourceView/sourceRect once they are set on creating the popover.
Now, the trick with animate(alongsideTransition: ((UIViewControllerTransitionCoordinatorContext) -> Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) is that you should update your constraints in alongsideTransition closure, not in completion. This way you ensure that UIPopoverPresentationController has the updated sourceRect when restoring the popover at the end of rotation.
What might seem counter-intuitive is that inside alongsideTransition closure you already have your new layout that you derive your constraints calculation from.
Here's an example in Swift:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
if self.popover != nil {
// optionally scroll to popover source rect, if inside scroll view
let rect = ...
self.scrollView.scrollRectToVisible(rect, animated: false)
// update source rect constraints
myConstraint.constant = ...
myConstrainedView.setNeedsLayout()
myConstrainedView.layoutIfNeeded()
}
}, completion: nil)
}
Very interesting - I got this to work without updating the position manually. I don't know why this works though.
let buttonContainer = UIView(frame: CGRectMake(0, 0, 44, 44))
let button = UIButton(frame: CGRectMake(0, 0, 44, 44))
buttonContainer.addSubview(button)
view.addSubview(buttonContainer)
popover!.presentPopoverFromRect(button, inView: button.superview!, permittedArrowDirections: .Any, animated: true)
Put the button that the popover is presenting from inside a "container view". Then the popover will automatically adjust location upon orientation change.

How to toggle status bar with a fade effect in iOS7 (like Photos app)?

I want to toggle the visibility of the status bar on tap, just like it does in the Photos app.
Prior to iOS 7, this code worked well:
-(void)setStatusBarIsHidden:(BOOL)statusBarIsHidden {
_statusBarIsHidden = statusBarIsHidden;
if (statusBarIsHidden == YES) {
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
}else{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
}
}
But I can't get it to work in iOS 7. All the answers that I found only offer suggestions for permanently hiding the bar but not toggling.
Yet, there must be a way since Photos does it.
By default on iOS 7 or above, to hide the status bar for a specific view controller, do the following:
if the view controller you want to hide the status bar with is being presented modally and the modalPresentationStyle is not UIModalPresentationFullScreen, manually set modalPresentationCapturesStatusBarAppearance to YES on the presented controller before it is presented (e.g. in -presentViewController:animated:completion or -prepareForSegue: if you're using storyboards)
override -prefersStatusBarHidden in the presented controller and return an appropriate value
call setNeedsStatusBarAppearanceUpdate on the presented controller
If you want to animate it's appearance or disappearance, do step three within an animation block:
[UIView animateWithDuration:0.33 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
You can also set the style of animation by returning an appropriate UIStatusBarAnimation value from -preferredStatusBarUpdateAnimation in the presented controller.
First set View controller-based status bar appearance in Info.plist to YES
This Swift Example shows how to toggle the StatusBar with an Animation, after pressing a Button.
import UIKit
class ToggleStatusBarViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prefersStatusBarHidden() -> Bool {
return !UIApplication.sharedApplication().statusBarHidden
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Slide
}
#IBAction func toggleStatusBar(sender: UIButton) {
UIView.animateWithDuration(0.5,
animations: {
self.setNeedsStatusBarAppearanceUpdate()
})
}
}
I was able to simplify #Jon's answer and still get behavior indistinguishable from the Photos app on iOS 7. It looks like the delayed update when showing isn't necessary.
- (IBAction)toggleUI:(id)sender {
self.hidesUI = !self.hidesUI;
CGRect barFrame = self.navigationController.navigationBar.frame;
CGFloat alpha = (self.hidesUI) ? 0.0 : 1.0;
[UIView animateWithDuration:0.33 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = alpha;
}];
self.navigationController.navigationBar.frame = CGRectZero;
self.navigationController.navigationBar.frame = barFrame;
}
- (BOOL)prefersStatusBarHidden {
return self.hidesUI;
}
This might be considered a bit of a hack but it's the closest I've come to reproducing the effect. There's still one minor issue. When fading out, you can see the navigation bar being resized from the top. It's subtle enough but still not a perfect fade. If anyone knows how to fix it, let me know!
- (BOOL)prefersStatusBarHidden {
if (_controlsAreHidden == YES)
return YES;
else
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationFade;
}
-(void)setControlsAreHidden:(BOOL)controlsAreHidden {
_controlsAreHidden = controlsAreHidden;
if (controlsAreHidden == YES) {
// fade out
//
CGRect barFrame = self.navigationController.navigationBar.frame;
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 0;
}];
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 44);
}else{
// fade in
//
CGRect barFrame = self.navigationController.navigationBar.frame;
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 64);
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 1;
}];
}
}
This code works perfectly fine:
-(void)setControlsAreHidden:(BOOL)controlsAreHidden {
if (_controlsAreHidden == controlsAreHidden)
return;
_controlsAreHidden = controlsAreHidden;
UINavigationBar * navigationBar = self.navigationController.navigationBar;
if (controlsAreHidden == YES) {
// fade out
//
CGRect barFrame = self.navigationController.navigationBar.frame;
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 0;
}];
self.navigationController.navigationBar.frame = CGRectZero;
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 44);
} else {
// fade in
//
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
}];
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.navigationController setNavigationBarHidden:NO animated:NO];
navigationBar.alpha = 0;
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^ {
navigationBar.alpha = 1;
}];
});
}
}
Actually there is now need to mess with navigation bar frames. You can achieve smooth animation just by using 2 separate animation blocks. Something like this should work just fine.
#property (nonatomic, assign) BOOL controlsShouldBeHidden;
...
- (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated {
if (self.controlsShouldBeHidden == hidden) {
return;
}
self.controlsShouldBeHidden = hidden;
NSTimeInterval duration = animated ? 0.3 : 0.0;
[UIView animateWithDuration:duration animations:^(void) {
[self setNeedsStatusBarAppearanceUpdate];
}];
[UIView animateWithDuration:duration animations:^(void) {
CGFloat alpha = hidden ? 0 : 1;
[self.navigationController.navigationBar setAlpha:alpha];
}];
}
- (BOOL)prefersStatusBarHidden {
return self.controlsShouldBeHidden;
}
For compatibility with iOS 6 just make sure to check [self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]
The way to resolve this depends on the value of the "View controller-based status bar appearance" setting in your app's plist.
If "View controller-based status bar appearance" is NO in your plist, then this code should work:
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
If "View controller-based status bar appearance" is on, in your view controllers, add this method:
- (BOOL) prefersStatusBarHidden {
// I've hardcoded to YES here, but you can return a dynamic value to meet your needs for toggling
return YES;
}
For toggling, when you want to change whether the status bar is hidden/shown based on the value of the above method, your view controller can call the setNeedsStatusBarAppearanceUpdate method.
To correct this issue with navigation bar sliding up when fading, you should add the following code:
self.navigationController.navigationBar.frame = CGRectZero;
into your "fade in" section before the following code line:
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 64);
This is necessary because the frame is the same and setting the same frame will be ignored and will not stop the navigation bar from sliding. Therefore you need to change the frame to something different and then set it again to the correct frame to trigger the change.

Add UISplitViewController via addChildViewController

I have one UIViewController in which another viewcontroller(1) and splitviewcontroller(2) do switching via addchildviewcontroller method. So when I add splitviewcontroller it doesn't handle correct the rotations. Look at the video – https://dl.dropbox.com/u/2139277/IMG_0180.MOV.
Here is the code that does switching:
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
if (fromViewController == toViewController)
return;
// animation setup
toViewController.view.frame = self.view.bounds;
// notify
[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
// select animation direction
UIViewAnimationOptions animation = (_contentState == ContentStateViewingMap) ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown;
// transition
ContentState previousState = _contentState;
_contentState = ContentStateAnimating;
[self transitionFromViewController:fromViewController
toViewController:toViewController
duration:0.6
options:animation | UIViewAnimationOptionCurveEaseInOut
animations:nil
completion:^(BOOL finished) {
[toViewController didMoveToParentViewController:self];
[fromViewController removeFromParentViewController];
_contentState = (previousState == ContentStateViewingMap) ? ContentStateViewingList : ContentStateViewingMap;
}];
}
AFAIK a UISplitViewController MUST be the root view controller of the window. Adding it as child view controller is not supported.

error in Button Jiggle algorithm

i have impletemented a button jiggle animation.where pressing a button wobbles ,but the problem is the animation does'nt stop and getting an error in [self.layer removeAllAnimations];
below is the code;
-(IBAction)button1Clicked:(id)sender
{
UIButton *no1 =sender;
output= [self answerCheck:no1.titleLabel.text];
self.label.text=output;
[self enableOptions:NO];
[self loadingView];
[self startJiggling:2];
}
- (void)startJiggling:(NSInteger)count
{
CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? +1 : -1 ) ));
CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? -1 : +1 ) ));
CGAffineTransform moveTransform = CGAffineTransformTranslate(rightWobble, -kAnimationTranslateX, -kAnimationTranslateY);
CGAffineTransform conCatTransform = CGAffineTransformConcat(rightWobble, moveTransform);
self.btnOption1.transform = leftWobble; // starting point
[UIView animateWithDuration:0.1
delay:(count * 0.08)
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{ self.btnOption1.transform = conCatTransform; }
completion:nil];
[self stopJiggling];
}
-(void)stopJiggling
{
[self.btnOption1.layer removeAllAnimations];
self.btnOption1.transform = CGAffineTransformIdentity; // Set it straight
}
You're setting the animation on self.btnOption1, so you would need to remove it from self.btnOption1:
- (void)stopJiggling {
[self.btnOption1.layer removeAllAnimations];
self.btnOption1.transform = CGAffineTransformIdentity;
}
but in fact if you just set the transform property of the button again, outside of an animation block, it will remove the animation:
- (void)stopJiggling {
self.btnOption1.transform = CGAffineTransformIdentity;
}
(This worked in my test project.)
Update:
I notice that you're starting the animation with a delay, and you're calling stopJiggling immediately after you call animateWithDuration:.... I don't know why you're using a delay or why you're calling stopJiggling immediately.
I created a test case to match your code:
#implementation ViewController {
__unsafe_unretained IBOutlet UIButton *btnOption1;
}
- (IBAction)startJiggling {
btnOption1.transform = CGAffineTransformMakeRotation(-.1);
[UIView animateWithDuration:.1 delay:2 * 0.08 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
btnOption1.transform = CGAffineTransformMakeRotation(.1);
} completion:nil];
[self stopJiggling];
}
- (void)stopJiggling {
[btnOption1.layer removeAllAnimations];
btnOption1.transform = CGAffineTransformIdentity;
}
#end
I hooked up my btnOption1 ivar to a button, and connected the button to the startJiggling method. With the code as shown, clicking the button does nothing, because the animation is removed immediately after it is added. If I comment out the removeAllAnimations message, clicking the button makes the button start jiggling and it jiggles forever. I tested on the iPhone 4.3 simulator, the iPhone 5.0 simulator, the iPhone 5.1 simulator, and my iPhone 4S running iOS 5.1.
So, I could not reproduce your problem. Sending removeAllAnimations removes the animation in my test.
I suspect that you just want the animation to repeat twice and then stop (since you have an argument named count and you're passing 2). If that's what you want to do, you can do it like this:
- (IBAction)startJiggling {
btnOption1.transform = CGAffineTransformMakeRotation(-.1);
[UIView animateWithDuration:.1 delay:2 * 0.08 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
[UIView setAnimationRepeatCount:2];
btnOption1.transform = CGAffineTransformMakeRotation(.1);
} completion:^(BOOL completed){
btnOption1.transform = CGAffineTransformIdentity;
}];
}
You set the repeat count inside the animation block using +[UIView setAnimationRepeatCount:], and you restore the button's transform in the completion block.
Remember to import QuartzCore/QuartzCore.h to talk with layers.

Closing a UIpicker in an iphone app

I'm new to the iphone dev. The app I'm making uses the picker to input value from the user. I have managed to make the picker hidden until the user hits the button. I used the mypicker.alpha = 0; in viewdidload so the the picker is invisible when the program starts. When the user hits the start button it executes the code mypicker.alpha=1;. I want the picker to close after the user chooses a value. How do I do that? anyone have any hints or tutorials ? I looked at few but they were confusing! Also how do I make the picker appear from the bottom up ? (like the keyboard !)
One method I recently started using is to put a shade button behind the picker, a large transparent black button the size of the screen, color black with alpha=0.3 ([UIColor colorWithWhite:0 alpha:0.3f] I think it was). This just puts a transparent "shade" over the rest of the screen except for the picker, similar to how it looks when you use UIAlertView. Then hook up the button so that it sends resignFirstResponder to the picker. Now when the user is done picking, they just tap anywhere outside the picker in the shaded area, and the button resigns the picker, and the picker can be slid down and the button faded out with an animation.
The picker slide up/down animation can be done and I have the code for it at home but don't have access to it right now. You can make it appear just like the keyboard and send the same notifications that the keyboard sends.
Don't use:
mypicker.alpha = 1;
mypicker.alpha = 0;
You should use:
mypicker.hidden = YES;
mypicker.hidden = NO;
in order to show or hide the picker.
In order to make it appear from the bottom, you can use block animations. I would use:
The .h file:
#interface viewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
BOOL shouldMoveDown;
IBOutlet UIPickerView * picker;
}
- (IBAction)movePicker;
The .m file:
#pragma mark - View lifecycle
- (void)viewDidLoad; {
[super viewDidLoad];
picker.hidden = YES;
shouldMoveDown = NO;
picker.userInteractionEnabled = NO;
}
- (IBAction)movePicker; {
if(shouldMoveDown){
[UIView animateWithDuration:1.0
animations:^{
CGRect newRect = picker.frame;
newRect.origin.y += 236; // 480 - 244 (Height of Picker) = 236
picker.frame = newRect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
animations:^{
picker.hidden = YES;
shouldMoveDown = NO;
picker.userInteractionEnabled = NO;
}
completion:^(BOOL finished){
;
}];
}];
}
else{
picker.hidden = NO;
//picker.frame = CGRectMake(picker.frame.origin.x, 480, picker.frame.size.width, picker.frame.size.height);
[UIView animateWithDuration:1.0
animations:^{
CGRect newRect = picker.frame;
newRect.origin.y -= 236; // 480 - 244 (Height of Picker) = 236
picker.frame = newRect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
animations:^{
shouldMoveDown = YES;
picker.userInteractionEnabled = YES;
}
completion:^(BOOL finished){
;
}];
}];
}
}
#pragma mark -
#pragma mark Picker Delegate Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView; {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component; {
return 1;
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; {
return #"1";
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component; {
}
Obviously you can set the picker up any way you would like to. You can also alter the speed at which this happens too! Hope this helps!