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.
Related
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
I have a simple animation that moves a slide up and down repeatedly. Here is the code:
CGRect frm_down = slider.frame;
frm_down.origin.y += 50;
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
slider.frame = frm_down;
}
completion:NULL];
This is pretty straight forward and works great; however, when I am presenting the view (self presentViewController:animated:) the animation does not happen.
In fact, the slider is INSTANTLY moved to the lower position (as if it called the animation only once and moved it back down, but not back up).
I have also tried this:
CGRect frm_down = [[[slider layer] presentationLayer] frame]
This will keep the slider in its original position instead of moving down once, and the animation still does not happen.
Any idea what I am missing? Thanks!
Your animation works. I tested it.
What you need is:
Instead of using:
self presentViewController:animated:
Use this:
[self addChildViewController:<YOUR_VIEWCONTROLLER>];
[self.view addSubview:<YOUR_VIEWCONTROLER>.view];
[<YOUR_VIEWCONTROLER> didMoveToParentViewController:self];
Addendum:
In your view controller's viewDidAppear, add the following code:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGRect frm_down = self.view.frame;
frm_down.origin.y += 50;
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
self.view.frame = frm_down;
}
completion:NULL];
}
It will animate when it comes into view.
I ran it as a test a priori. Hope it helps.
On Swift :
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
var from_down = self.view.frame
from_down.origin.y += 50
UIView.animate(withDuration: 0.2, delay: 0.0, options: .autoreverse, animations: {
self.view.frame = from_down
}, completion: nil)
}
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.
I'm attempting to fade in a UIView that I've created by animating the alpha. I need to fade it in, leave it visible for a few seconds, then fade it out.
The fade out function works fine. The view smoothly disappears. But the fade in just makes the view appear instantly instead of slowly appearing over an interval of 0.5 seconds.
So it seems like the fade in animation isn't working, just instantly setting the alpha to 1.0. I'm kind of at a loss here. Any ideas what I'm doing wrong? Thanks!
-(void)presentPopupPhrase:(NSString *)phrase
inView:(UIView *)view
withDelegate:(id)delegate
andCompletion:(void (^)(BOOL completed))completion {
MessagePopupView *pv = [[[MessagePopupView alloc] initWithFrame:self.frame andText:phrase] autorelease];
pv.alpha = 0.0;
[view addSubview:pv];
[self fadeInMPV:pv
withDuration:self.fadeDuration
andDelay:self.fadeInDelay];
[self fadeOutMPV:pv
withDuration:self.fadeDuration
afterDelay:self.fadeOutDelay
withCompletion:completion
andDelegate:delegate];
}
-(void)fadeInMPV:(MessagePopupView *)mpv
withDuration:(NSTimeInterval)duration
andDelay:(NSTimeInterval)delay
{
[UIView animateWithDuration:duration
delay:delay
options:UIViewAnimationOptionCurveLinear
animations:^{
mpv.alpha = 1.0;
}
completion:nil];
}
-(void)fadeOutMPV:(MessagePopupView *)mpv
withDuration:(NSTimeInterval)duration
afterDelay:(NSTimeInterval)delay
withCompletion:(void (^)(BOOL completed))completion
andDelegate:(id)delegate
{
[UIView animateWithDuration:duration
delay:delay
options:UIViewAnimationOptionCurveLinear
animations:^{
mpv.alpha = 0.0;
}
completion:completion];
}
EDIT:
If it helps, here's the VC code where I'm calling it from:
-(void)viewDidAppear:(BOOL)animated {
CGRect phraseFrame = CGRectMake(20, 341, 280, 65);
PopupPhraseController *phraseController = [[[PopupPhraseController alloc] initWithFrame:phraseFrame] autorelease];
[phraseController presentPopupPhrase:#"Test Phrase" inView:self.view withDelegate:self andCompletion:^(BOOL completed){
if (completed) {
NSLog(#"completed");
} else {
NSLog(#"not completed");
}
NSLog(#"blocked!");
}];
[super viewDidAppear:animated];
}
You can't chain the animations like that as the second animation block essentially causes the first one to be cancelled out.
You have two options for Linking Multiple Animations Together:
Use the completion handler of the first animation
Nest the animations but delay the second one
Looks something like this
[UIView animateWithDuration:self.fadeDuration
delay:self.fadeInDelay
options:UIViewAnimationOptionCurveLinear
animations:^{
pv.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:self.fadeDuration
delay:self.fadeOutDelay
options:UIViewAnimationOptionCurveLinear
animations:^{
pv.alpha = 0.0;
} completion:completion];
}];
Looks something like this
[UIView animateWithDuration:self.fadeDuration
delay:self.fadeInDelay
options:UIViewAnimationOptionCurveLinear
animations:^{
pv.alpha = 1.0;
[UIView animateWithDuration:self.fadeDuration
delay:self.fadeOutDelay + self.fadeDuration
options:UIViewAnimationOptionCurveLinear
animations:^{
pv.alpha = 0.0;
} completion:completion];
} completion:nil];
The issue is because of the way you are setting up the animations.
When you set animatable properties on a view the backing model of the view is updated instantly. So when you set the alpha = 1.0 in the first block the backing data model for the view has the alpha as 1.0 and then the actual animation is kicked off on another thread to show the interpolation between the two values.
When you define the second block straight after the first the view essentially says "ok I need to animate from 1.0 (my current value in the model) to 0.0", which is why you don't see what you expected.
Thanks to Paul.s for dropping the hint there. I think this expected behaviour is a little weird, even if it seems logical from a low level perspective.
To expand on Paul's 2 solutions, there is a 3rd solution which is better IMO.
Use GCD to add a delay to the fade out code, like such:
//Make sure this delay exceeds your fade-in time...
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self fadeOutMPV:pv
withDuration:self.fadeDuration
afterDelay:self.fadeOutDelay
withCompletion:completion
andDelegate:delegate];
});
This solution's better because the executing view controller has complete control on not only when, but what gets to trigger the fade out (for example, a user action).
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!