UIPickerView : Keyboard not hiding - objective-c

I have 3 UITexfield, the user can fill in the first two, but the last one is a category field and displays a UIPickerView when it's clicked.
What I've managed to do so far is :
The user clicks on the catergory textfield -> the picker view appears
Then the user clicks on another textfield -> the picker view disappears and the keyboard shows up
But know I would like to hide the keyboard when the user clicks agains on the category textfield and show the picker view.
This is what I have so far :
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField == categoryTextField){
[categoryTextField resignFirstResponder];
[UIView beginAnimations:#"picker" context:nil];
[UIView setAnimationDuration:0.3];
pickerView.transform = CGAffineTransformMakeTranslation(0,-236);
[UIView commitAnimations];
}else{
[UIView beginAnimations:#"picker" context:nil];
[UIView setAnimationDuration:0.3];
pickerView.transform = CGAffineTransformMakeTranslation(0,236);
[UIView commitAnimations];
}
}
But it doesn't work. Any thought why ?

You're making it too difficult. Set the picker view as the input view of the textfield, and the OS will take care of the animations for you. As each field becomes first responder, the appropriate input view (default keyboard for the text ones, your picker for the third one) will be displayed. You don't need to do any animations yourself.

I don't really see where your problem comes from. I think that maybe your translation makes the pickerView move too far. You should try that :
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField == categoryTextField){
[categoryTextField resignFirstResponder];
[UIView beginAnimations:#"picker" context:nil];
[UIView setAnimationDuration:0.3];
CGRect frame = pickerView.frame;
frame.origin.y = 480 - 236; // assuming your on an iPhone and your picker appears from bottom
pickerView.frame = frame;
[UIView commitAnimations];
}else{
[UIView beginAnimations:#"picker" context:nil];
[UIView setAnimationDuration:0.3];
CGRect frame = pickerView.frame;
frame.origin.y = 480; // assuming your on an iPhone and your picker disappears to bottom
pickerView.frame = frame;
[UIView commitAnimations];
}
}
Hope that helps

Related

Rotating One UIView Causes Another To Be Pushed OffScreen

I have a ViewController which contains a couple of UILabels, a UIImageView and an ADBannerView. There are two relevant movements: The UIImageView rotates based on the angle at which the user is holding their device, and the ADBannerView slides into view based on whether it has an iAD to display.
If the UIImageView is stationary, the ADBannerView slides into view correctly. However, once the UIImageView starts rotating, the ADBannerView disappears. AFAIK the two views are completely independent.
- (void) updateFloatingBar
{
double angleToUpright = [self calculateAngleToUpright];
double newAngle = angleToUpright - self.currentAngle;
[self.FloatingBarImageView setTransform:CGAffineTransformMakeRotation(newAngle*(CGFloat)(M_PI/180))];
}
- (void) hideAd
{
NSLog(#"Ad Hidden");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.adBannerView cache:YES];
self.adBannerView.frame = CGRectMake(0,self.view.bounds.size.height + 50,50,320);
[UIView commitAnimations];
}
- (void) showAd
{
NSLog(#"Ad Shown");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.compassADBannerView cache:YES];
self.compassADBannerView.frame = CGRectMake(0,self.view.bounds.size.height - 50,50,320);
[UIView commitAnimations];
}
Again, the first method works correctly, it just also has the secondary effect of pushing offscreen the adBannerView placed by showAd:

How to replace button with an animation in Xcode

I have a UIButton in my code that moves steadily across the screen. Currently, when the user presses the button, the alpha changes to 0 and it just disappears. What I'd like to do is run a separate animation after the button is pressed/it has disappeared. Seems easy enough but the catch is I need to run the animation at the exact point of the button when it is pressed. And I'm drawing a blank on how to make this happen. Any help will be much appreciated! I'll post some relevant code below.
-(void)movingbuttons{
movingButton2.center = CGPointMake(x, y);
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(moveObject)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)moveObject{
movingButton2.center = CGPointMake(movingButton2.center.x , movingButton2.center.y +1);
}
-(IBAction)button2:(id)sender {
[UIView beginAnimations:nil context:NULL];
[movingButton2 setAlpha:0];
[UIView commitAnimations];
}
Replace your button2 action with below code and implement the someOtherMethodWithAnimation method with the animation you want :)
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
movingButton2.alpha = 0;
[UIView commitAnimations];
[self performSelector:#selector(someOtherMethodWithAnimation) withObject:nil afterDelay:1.0];
Replace your animation with:
[UIView animateWithDuration:0.25
animations:^{
self.movingbutton2.alpha = 0.0;
// modify other animatable view properties here, ex:
self.someOtherView.alpha = 1.0;
}
completion:nil];
Just a nit picking point, but is the button in your view controller's .xib file correctly hooked up to your IBOutlets and IBActions?
UPDATE:
You are not limited to modifying that one button in your method. You add what ever code you want in the animation block (see the udated axample above).
UIView animatable properties, there is an animation section there.
Another approach could be (I am just using alpha as an example):
[UIView animateWithDuration:1.0
animations:^{
self.movingButton2.alpha = 0.0;
}
completion:^{
[UIView animatateWithDuration:0.25
animations:^{
self.someOtherView.alpha = 1.0;
}
completion:nil];
}];
This will more likely guarantee the animations will hapen one after another.

How can I program a custom partial or sub view for a calculator?

I'm building a basic calculator app. The calculator is already fully functional with basic features. The problem I'm having is I ran out of room on the screen to add other, more advanced features. Ideally what I would like to do is create some kind of subclass and view that slides up to to the bottom of the label (where the completed calculations are displayed), when a button on the bottom of the screen is pressed. In other words, I want a view with more operators and computation options to slide up to the bottom of the label and I dont want this view to cover up any digits that are being displayed in the label. Is there anyway to achieve this?
Yes, you can. When your button is pressed, create your new view (with the extra functions), add it as a subview to self.view, and animate a change to it's frame, so that it's frame changes from below the visible view to just below your digits.
Like this:
-(void) buttonPressed {
UIView *myNewView = << create your view >>
myNewView.frame = CGRectMake(0,480, 320,200); // or whatever your width and height are
// 480 means it will be below the visible frame.
[self.view addSubview: myNewView];
float bottom_Y_of_digit_display = 100;// or wherever it is...
[UIView beginAnimations:nil contenxt:nil];
[UIView setAnimationDelay: 0.0];
[UIView setAnimationDuration: 1.0]; // one second.
myNewView.frame = CGRectMake(0,bottom_y_of_digit_display, 320,200);
[UIView commitAnimations];
}
You can use UIAnimations to create an animation out of any changes to UIView properties. You can make your UIView hidden by settings its frame.origin.y to 480 and then change the rect and wrap it in a UIAnimation.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
[UIView commitAnimations];
UPDATE
If you are targeting iOS 4.0 and later then you should use the new UIAnimations interface.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:0.75 delay:0 options:options
animations:^(){
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
}
completion:^(BOOL finished){
//Do something upon completion
}];

iOS - animating UIView on iPad, change x origin and width simultaneously?

I'm having some trouble with UIView animations on iPad.
I'm working on a project in which I have implemented a "facebook style" menu on the left, using the JTRevealSidebar framework.
This framework works perfectly, however, instead of "pushing" the right side view off the screen, I would like to resize it, so the user can still see the whole content of the right-side view.
I have managed to do this by changing the view's frame as well as doing the offset.
This is what it looks like with the sidebar open:
And when it's closed:
This right-side view contains a navigation bar with two buttons (one button on the left to toggle the left sidebar, and another button on the right to dismiss the controller), and the content itself is a simple UIWebView.
The problem I am facing is during the animation (from the full-screen state to the sidebar open state):
When I change the view's frame, even after doing the translate, the view resizes before the animation starts, which gives a weird effect like this:
I would like to keep the right side of the webview anchored to the right side of the screen and only have the left side change position when animating (basicaly so that the "done" button is always in the same position).
Here is the animation code:
- (void)revealSidebar:(BOOL)shouldReveal {
if (shouldReveal) {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
// Push the view to the right
contentView.transform = CGAffineTransformTranslate(contentView.transform, CGRectGetWidth(sidebarView.frame), 0);
// Resize the view so it fits on remaining part of the screen
contentView.frame = CGRectMake(contentView.frame.origin.x, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);
// The problem is here: the view's frame is changed before the
// Translate transformation actualy starts...
//
// Is there a way to change the x origin and the width simultaneously ?
[UIView commitAnimations];
} else {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
// Reset the frame so that it takes up whole screen
contentView.frame = CGRectMake(contentView.bounds.origin.x,contentView.bounds.origin.y,contentView.frame.size.width+sidebarView.frame.size.width,contentView.frame.size.height);
[UIView commitAnimations];
}
_state.isShowing = shouldReveal ? 1 : 0;
}
I've had no luck so far, and was wandering if anyone had any ideas as to how I could achieve this.
Thank you
EDIT 2:
It seems that the subviews are being immediately resized dueto translations being used. So maybe you could just animate the move to the right and then when that has finished set the width:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
contentView.frame = CGRectMake(CGRectGetWidth(sidebarView.frame), 0, contentView.frame.size.width-CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
}
- (void)animationDidStopBack:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
contentView.frame = contentView.bounds;
}
- (void)revealSidebar:(BOOL)shouldReveal {
if (shouldReveal) {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.1];
[UIView setAnimationDelegate:self];
contentView.frame = CGRectOffset(contentView.bounds, CGRectGetWidth(sidebarView.frame), 0);
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView commitAnimations];
} else {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
contentView.frame = CGRectMake(0, 0, contentView.frame.size.width+CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
[UIView setAnimationDidStopSelector:#selector(animationDidStopBack:finished:context:)];
[UIView commitAnimations];
}
_state.isShowing = shouldReveal ? 1 : 0;
}
It's not perfect but does avoid the blank space on the right and I feel looks better because of that. Particularly if you speed up the animation.
EDIT 1:
try:
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
if (shouldReveal) {
contentView.frame = CGRectMake(CGRectGetWidth(sidebarView.frame), 0, contentView.frame.size.width-CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
} else {
contentView.frame = CGRectMake(0, 0, contentView.frame.size.width+CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
}
[UIView commitAnimations];
Old Answer:
sounds /looks like you just need your x position modifying to always be at the edge of the sidebar. untested code assuming your contentview's origin is at far left:
- (void)revealSidebar:(BOOL)shouldReveal {
if (shouldReveal) {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
// Push the view to the right
contentView.transform = CGAffineTransformTranslate(contentView.transform, CGRectGetWidth(sidebarView.frame), 0);
// Resize the view so it fits on remaining part of the screen
contentView.frame = CGRectMake(contentView.frame.origin.x, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);
[UIView commitAnimations];
} else {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.3];
// Resize the view so it fits on full screen
contentView.frame = CGRectMake(sidebarView.frame.size.width, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);
[UIView commitAnimations];
}
_state.isShowing = shouldReveal ? 1 : 0;
}
if the origin is actually centred then:
contentView.frame = CGRectMake(sidebarView.frame.size.width+(contentView.frame.size.width/2), contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);

How to stop an UIView animation

I have several UIImageViews within a UIScrollView that I want to wiggle when the user long-presses one of them. So similar to the behavior you get when you long-press an icon in your iPad/iPhone menu.
So I have the following:
- (void)startWiggling {
for (UIImageView *touchView in [scrollView subviews]) {
[UIView beginAnimations:#"wiggle" context:nil];
[UIView setAnimationDuration:0.1];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:FLT_MAX];
//wiggle 1 degree both sides
touchView.transform = CGAffineTransformMakeRotation();
touchView.transform = CGAffineTransformMakeRotation(-0.0174532925);
[UIView commitAnimations];
}
}
- (void)stopWiggling {
NSLog(#"Stop wiggling");
}
This works fine. The issue is... How can I make it stop wiggling after the user has pressed a button? I have a button and connected it etc and it's reaching the stopWiggling method, so that's fine. But so...
How do I remove the UIView animation from these UIImageViews?
Can I bind this action to the user pressing the home button on their device?
#import <QuartzCore/QuartzCore.h>
then
[myView.layer removeAllAnimations];
or
[self.view.layer removeAllAnimations];