showing and hiding a UIView - ios

I have used the below code to position a UIView which will hold various buttons ect. I am showing this view in an IBAction method for a button.
How would I have the user be able to click on the button to show the UIView in a default position, then, when the user clicks on the button again, move the UIView back off screen?
Am I doing the best thing moving the UIView on/off screen or would it be better to just hide/show the controller?
I like the idea of moving it as it kinda looks like its moving downward (not that its animated or anything). Actualy how would I animate this to move slower?
CGRect f = self.optionsuiview.frame;
f.origin.x = 0;
f.origin.y = 42;
self.optionsuiview.frame = f;

If you create a property of the button (ctrl+drag to header file) you can use this to change the state of the button, so you can dictate when the view moves up/down.
#property (strong, nonatomic) IBOutlet UIButton *yourButton;
Within your IBAction method could look something like this
-(IBAction)yourButtonPressed:(id)sender{
if (self.yourButton.selected){
self.yourButton.selected = NO;
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.optionsuiview.frame;
f.origin.x = 0;
f.origin.y = 42;
self.optionsuiview.frame = f;
}];
}
if (!self.yourButton.selected){
self.yourButton.selected = YES;
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.optionsuiview.frame;
f.origin.x = 0;
f.origin.y = 0;
self.optionsuiview.frame = f;
}];
}
I hope this way helps with what you're looking for ,
Cheers, Jim.

Am i doing the best thing moving the uiview on/off screen or would it be better to just hide/show the controller?
Only you or your UX advisor can answer that...
You would hide the view again in the same way you show it, by changing the view frame. It's just that to hide it you're setting the frame to a location that is off screen. And the same logic applies for animation too:
// to show
// calculate `f` here to a location off screen to animate to
[UIView animateWithDuration:0.2
animations:^{
self.optionsuiview.frame = f;
}
completion:^{
self.optionsuiview.hidden = YES;
}];
(note that we hide the view after the animation so it isn't considered a tap target)
Showing the view is the same in reverse. Set hidden to NO and then animate the frame to a visible location.

Related

Animating a UIButton to fullscreen

so I have a very simple button that when clicked goes to fullscreen and when clicked again goes back to the same position it was initially in. For some reason it works perfectly without the animation. When I uncomment the animation part when I initially click the button it does nothing, the second time I click it slightly enlarges. The third time I click it animates slowly but back to it's smaller original size... Why is it animating the opposite way?
- (IBAction)viewImage1:(id)sender {
UIButton *btn = (UIButton*) sender;
if (btn.tag == 0)
{
CGRect r = [[UIScreen mainScreen] bounds];
/*[UIView animateWithDuration:0.5f delay:0.0f options:0 animations:^{*/
[sender setFrame: r];
/*}completion:nil];*/
btn.tag = 1;
}
else
{
btn.tag = 0;
[sender setFrame:CGRectMake(0,0,370,200)];
}
}
There are two solutions to your problem either of which will work:
Disable Autolayout. (discouraged)
You can do that in Interface Builder by opening the File Inspector
in the right pane and unchecking the respective check box.
However, if you want to use Autolayout for constraining other UI elements in your view (which is quite a good idea in most cases) this approach won't work which is why I would recommend the second solution:
Keep Autolayout enabled, create an outlet for your button in your view controller and set
self.myButton.translatesAutoresizingMaskIntoConstraints = YES;
in your view controller's viewDidLoad method.
You could also add layout constraints to your button and animate those. (This excellent Stackoverflow post explains how it's done.)
The reason for this tricky behavior is that once you enable Autolayout a view's frame is no longer relevant to the actual layout that appears on screen, only the view's layout constraints matter. Setting its translatesAutoresizingMaskIntoConstraints property to YES causes the system to automatically create layout constraints for your view that will "emulate" the frame you set, in a manner of speaking.
It is easier to do this with auto layout and constraints. Create an IBOutlet for the height constraint of your button call it something like btnHeight. Do the same for the width constraint call it something like btnWidth. Then create an IBAction like so:
- (IBAction)buttonPress:(UIButton *)sender {
UIButton *btn = (UIButton *) sender;
CGRect r = [[UIScreen mainScreen] bounds];
if (CGRectEqualToRect(btn.frame, CGRectMake(0.0, 0.0, 370, 200))) {
[UIView animateWithDuration:0.5 delay:0.0 options:0 animations:^{
self.btnHeight.constant = r.size.height;
self.btnWidth.constant = r.size.width;
[self.view layoutIfNeeded];
} completion:^(BOOL finished){
}];
}else{
[UIView animateWithDuration:0.5 delay:0.0 options:0 animations:^{
self.btnHeight.constant = 200.0;
self.btnWidth.constant = 370.0;
[self.view layoutIfNeeded];
} completion:^(BOOL finished){
}];
}
}
In my experience animating the frame of a UIButton does not work well, a, the only method, I'm aware of, is to use CGAffineTransformScale which will rasterize the title of the button and scale it as well.

Move UIToolBar above keyboard on screen with UIScrollview

I have a screen within an iPhone app that consist of a UITextView. This text view is contained within a UIScrollView. The purpose of the screen is for the user to type in text, and to optionally attach an image to what he is writing. Therefore, the screen also has a UIToolbar with a camera button at the bottom of the screen. The structure of the screen is as follows:
-View
--UIScrollView
---UITextView
--UIToolbar
---UIButton
When the user navigates to this screen, the viewDidAppear method assigns first responder to the uitextview element, so the keyboard shows up, which hides the toolbar and the camera button.
I would like the entire toolbar to re-draw itself right above the keyboard, and to position itself again at the bottom of the screen when the keyboard hides.
I have found related posts on SO (like this one). However, such methods introduce undesired behaviours. For example, implementing the solution in the article above, the toolbar does move with the keyboard, but the UIScrollView gets its frame.origin.y coordinate shifted way above the top of the screen, so it's impossible for the user to see what he is typing.
I have also tried to reset the frame of the toolbar, by adding it as an IBOutlet and using cgrectmake to reposition it. However, after several tries, the toolbar remains stuck at the bottom of the screen and hidden by the keyboard:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:<#(UIViewAnimationCurve)#>]
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.keyboardToolbar.frame.origin.y - 280;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
I have tried several iterations similar to the code above and they all fail at repositioning the toolbar.
So in short, what is the right way to float a toolbar right on top of a keyboard in a screen whose space is completely utilised by a uitextview element?
Thanks to RoryMcKinnel for the pointer. As the article referenced is in Swift, I thought I might paste the solution that worked for be on ObjC
- (void)keyboardWillShowNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertedKeyboardFrame = [self.view convertRect:keyboardEndFrame fromView:self.view.window];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = CGRectGetMaxY(self.view.bounds) - CGRectGetMinY(convertedKeyboardFrame);
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}
Bear in mind, this code did make the toolbar move as required, but the toolbar was not visible at all. It turned out that it was being hidden behind the UIScrollView. This was easily fixed by shifting the order between the scroll view and the toolbar element in the IB hierarchy.
The method above works for the keyboardWillShow event. You'll need to add the corresponding one for when the keyboard hides, like this:
- (void)keyboardWillHideNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = 0.0f;
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}

IOS - buttons slide in from right side animation

i am new to IOS programming. i have a background image on my screen. What i want is when app launches screen shows with the background image and then after 1 sec 2 buttons comes up from right side of the screen. how can i do this. here is the image what i am trying to do
button 1 and button2 have to be invisible first. after 1 second they comes up from right side.
if there are any tutorials related to this kind of animation then please share
You can use simple UIView Animations to achieve this.
Set your button x origin any value greater than screen size so that it is not visible first. Then reset the button frame to a visible value with view animation. For example call the following function in your viewWillAppear: method.
- (void) animateButton {
// Setting button origin to value greater than the view width.
CGRect frame = button.frame;
frame.origin.x = self.view.frame.size.width+10;// or set any value > 320
button.frame = frame;
[UIView animateWithDuration:0.5
delay:2.0
options: UIViewAnimationCurveEaseOut
animations:^{
button.frame = CGRectMake(20, 100, 60, 25) ;// Any value according to your requirement
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
Refer Tutorial
You can do it this way, please note that, if you want to animate the way your button shows up, you must hide them using alpha = 0.0f (and not hidden = true). This way, you will have a smooth showing up animation !
Here it is :
First, on your viewDidLoad of your UIViewController, you have to set up a NSTimer of 1sec, then let it call the method that will let your buttons appear :
- (void) viewDidLoad {
[super viewDidLoad];
// Do your init stuff here
// We will call your buttons as if they are declared as properties of your class, ask if you don't know how to set them
self.button1.alpha = 0.0f;
self.button2.alpha = 0.0f;
// This will wait 1 sec until calling showButtons, where we will do the trick
NSTimeInterval timeInterval = 1.0;
[NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:#selector(showButtons) userInfo:nil repeats:NO];
}
- (void) showButtons {
[UIView beginAnimations:#"buttonShowUp" context:nil];
[UIView setAnimationDuration:0.5]; // Set it as you want, it's the length of your animation
self.button1.alpha = 1.0f;
self.button2.alpha = 1.0f;
// If you want to move them from right to left, here is how we gonna do it :
float move = 100.0f; // Set it the way you want it
self.button1.frame = CGRectMake(self.button1.frame.origin.x - move,
self.button1.frame.origin.y,
self.button1.frame.size.width,
self.button1.frame.size.height);
self.button2.frame = CGRectMake(self.button2.frame.origin.x - move,
self.button2.frame.origin.y,
self.button2.frame.size.width,
self.button2.frame.size.height);
// If you want to set them in the exact center of your view, you can replace
// self.button1.frame.origin.x - move
// by the following
// (self.view.center - self.button1.frame.size.width/2)
// This way, your button will be centered horizontally
[UIView commitAnimations];
}
Ask if you have any questions !
Set the buttons' x co-ordinates such that the button is just outside the screen on the right side.
And then try the following in your viewDidLoad()
[UIView animateWithDuration:0.5
delay:1.0
options:NO
animations:^{ change your button x co- ordinate here to the co-ordinate you need it on finally}
completion:NULL];

Animated UIButtons snap back to original position after opening UIAlertView

I am making a Welcome screen with two UITextFields, a Forgot Password button and two additional buttons (signInButton and createAccountButton). These two buttons are placed in an UIView (inputsView) along with the text fields.
As soon as one of the text fields is focused, I animate the screen to adjust for the keyboard, resize the createAccountButton button and slide in the signInButton. I'm using the following code:
[UIView animateWithDuration:.48 delay:0 usingSpringWithDamping:1 initialSpringVelocity:.42 options:(UIViewAnimationOptionBeginFromCurrentState) animations:^{
CGRect f3 = inputsView.frame;
f3.origin.y = 112;
inputsView.frame = f3;
[inputsView layoutSubviews];
CGRect f4 = createAccountButton.bounds;
f4.size.width = 160;
createAccountButton.bounds = f4;
CGRect f5 = createAccountButton.frame;
f5.origin.x = 160;
createAccountButton.frame = f5;
CGRect f6 = signInButton.frame;
f6.origin.x = 0;
signInButton.frame = f6;
CGRect f7 = buttonSeparator.frame;
f7.origin.x = 160;
buttonSeparator.frame = f7;
[signInButton layoutSubviews];
[createAccountButton layoutSubviews];
} completion:nil];
This all works fine, but if I then tap the Forgot Password button to open a UIAlertView, the buttons pop back to their original positions. Strangely enough, the buttonSeparator, which is a 1px UIView does not snap back.
Am I forgetting something, or is this a bug in the iOS 7 SDK?
Most likely you are using autolayout
Disable the autolayout property.
Reason why its happening : Autolayout will update the views to their original position using current constraints.
Hope it helps.

UIButton not responding after animation

I would prefer first download the project from below link and then continue with question (only 36kb)
Download Link
At start what I have is like below.
When I click My Office button, I am calling action actionSeenButton which will print NSLog(#"actionSeenButton");
- (IBAction)actionSeenButton:(id)sender {
NSLog(#"actionSeenButton");
}
This works perfect.
When I click, Show hidden button, I am sliding view by 100 and showing the image and buttons that I have at the top, as shown in below image
Code used is
- (IBAction)showHiddenButton:(id)sender {
CGAffineTransform translation = CGAffineTransformIdentity;
translation = CGAffineTransformMakeTranslation(0, 100);
[UIView beginAnimations:nil context:nil];
self.view.transform = translation;
[UIView commitAnimations];
}
When I click this button, I am calling action actionHiddenButton which will print NSLog(#"actionHiddenButton");
- (IBAction)actionHiddenButton:(id)sender {
NSLog(#"actionHiddenButton");
}
BUT the problem is, when I click the new button that I see, action is not getting called.
Any idea why this is happening?
Note
When I move the top hidden button from y=-70 to y=170, action is getting called.
Sample project can be downloaded from here
What I wanted to implement is, showing three buttons (as menu) on the top in one line by moving view down.
verify that your button is not behind the frame of another view. even if the button is visable, if there is something covering it up it wont work. i don't have access to xcode at the moment but my guess is your view "stack" is prohibiting you from interacting with the button. a button is esentually a uiview and you can do all the same animations to buttons and labels that you can with views. your best bet is to leave the view in the background alone and just move your buttons. since your "hidden" button isn't part of your main "view" hiarchy thats where your problem is.
upon further investigation, your problem is related to auto-layout and making sure your button object stays in the view hierarchy. if you turn off auto-layout you will see where the problem is. when you animate the main view down the "hidden" button is off of the view and there for inactive. the easiest solution is to just animate the buttons. the next best solution closest to what you have is to add another view onto your "main view" and then put the buttons into that view. also why do you have that background image twice? why not just set the background color of your view to that same yellow?
I downloaded your project and it seems the translation you're making for self.view. So the actionHiddenButton is not in the frame.Its better to have the controls you want to animate in the separate view.
If you want to see the problem, after your view get transformed set clipsToBounds to YES. Like
self.view.transform = translation;
self.view.clipsToBounds = YES;
Yipeee!!! Below is how I did.
.h
Added new variable.
#property (retain, nonatomic) NSString *hideStatus;
.m
-(void) viewDidAppear:(BOOL)animated {
NSLog(#"viewDidAppear");
CGAffineTransform translation = CGAffineTransformIdentity;
translation = CGAffineTransformMakeTranslation(0, -100);
self.view.transform = translation;
self.view.clipsToBounds = YES;
[UIView commitAnimations];
self.view.frame = CGRectMake(0,-80,320,560);
hideStatus = #"hidden";
}
- (IBAction)showHiddenButton:(id)sender {
NSLog(#"hideStatus===%#", hideStatus);
CGAffineTransform translation = CGAffineTransformIdentity;
if ([hideStatus isEqualToString:#"hidden"]) {
translation = CGAffineTransformMakeTranslation(0, 0);
hideStatus = #"shown";
} else {
translation = CGAffineTransformMakeTranslation(0, -100);
hideStatus = #"hidden";
}
[UIView beginAnimations:nil context:nil];
self.view.transform = translation;
self.view.clipsToBounds = YES;
[UIView commitAnimations];
}
Attached is the sample project. You can download from here.

Resources