NavigationController UIToolbar Change Items - iphone

I want to change the items in my UIToolbar by hiding the toolbar, changing the items (button, fixed space, etc), and revealing it again.
I currently have a button on my UIToolbar that, when pressed, hides the toolbar by calling [[self navigationController]setToolbarHidden:YES animated:YES];.
How can I set these items? Is it possible using interface builder or do I need to hard-code them in?

This is non-standard behavior, but should be doable. You might consider instead of removing and adding new buttons to the existing toolbar, to instead create a different toolbar that gets faded in instead. This would make things easier to code/debug. In general, it just requires less "mess."
To achieve the desired behavior, you could do something like:
float animationDuration = .25;
[UIView animateWithDuration:animationDuration animations:*{
// Remove the old toolbar.
self.oldToolbar.alpha = 0;
// Fade the new toolbar in.
self.newToolbar.alpha = 1;
}];
This example assumes that you have already loaded your other toolbar into the newToolbar property. Let me know if you need further assistance or any explanation.

You can set new items for the toolbar this way:
[toolbar setItems:<new_items_array> animated:YES];
It will also animate the change so you may not need to hide and show it again, which is not a good UI practice in general.

A bit of an odd one... this is a bit hacky but should be perfectly fine:
[UIView animateWithDuration:0.5f animations:^{
// Remove the old toolbar.
self.oldToolbar.alpha = 0;
} completion:^(BOOL finished) {
//add code to change toolbar.
[UIView animateWithDuration:0.5f animations:^{
// Fade the new toolbar in.
self.newToolbar.alpha = 1;
}];
}];

Related

Make move animation permanent in iOS

I am trying to make a simple application where there are 3 buttons. When user clicks any of the button, they are animated(moved) to their new positions! All this works from this code:
[UIView animateWithDuration:1.2
delay:0.1
options: UIViewAnimationCurveEaseOut
animations:^
{
//Moving the Sum (UIButton which will move through this animation)
CGRect frame = Sum.frame;
frame.origin.y = -20;
frame.origin.x = (-120);
Sum.frame = frame;
.....
....
}
completion:^(BOOL finished)
{
NSLog(#"Completed");
//adding subview after the animation is complete! newView is an example!
[self.view addSubview:newView];}];
The Problem is that once i add a subview to the main view, All buttons come back to their old position! meaning they weren't moved permanently.. how can i solve this? Plz help guys!
What happens when you add a view? A layout is performed. You could have done two mistakes
You are using autolayout.
If you are using autolayout, changing frames directly is not advised and a relayout will update the views to their original position using current constraints.
You are setting the frame position in layoutSubviews, viewWillLayout or viewDidLayout.
Check where you are setting the original position. Can the method be called multiple times?
You have save the X,Y Position of the new frame & then set this frame by coding.

UIView not animating the first time

This code animates my view every time it's run, except for the first time. When the keyboard is displayed or hidden, a UIView is repositioned:
[UIView
animateWithDuration:0.26
animations:^{
[self setupActiveOverlayViewFrame];
}completion:nil];
-(void)setupActiveOverlayViewFrame {
float optimalOverlayHeight = [self.activePanel optimalHeight];
float realOverlayHeight = MIN(optimalOverlayHeight, self.displayView.frame.size.height);
if (self.activePanel.frame.size.height != realOverlayHeight) {
self.activePanel.frame = CGRectMake(self.activePanel.frame.origin.x, 0, self.activePanel.frame.size.width, realOverlayHeight);
}
self.activePanel.center = [self correctCenterForOverlay];
}
The method I posted is just to show that all it does is re-size and re-position it.
The first time this code is run, it doesn't animate. It just jumps into position. Every time after that, it animates correctly.
Its possible that the "keyboard did display" notification is being called before your view is fully set up, like if you've pushed a view controller onto a navigation controller and immediately give a text view focus on viewDidLoad
You can either keep track of when the keyboard is up or down and when viewDidAppear is called, check if the keyboard is up, and run it. Or you can postpone giving focus to a text view/field until viewDidAppear: is called.
I got the same problem. I want to advice you to check Panel center before(!) animating to find out has it right position at the first run. If it's not. Just set right position. Also try the next code
[self setupActiveOverlayViewFrame];
[UIView animateWithDuration:0.26
animations:^{
[self.view layoutIfNeeded];
}completion:nil];
P.S. If you are using autolayout better use constraints to move your views using the code above.

Application Design - Menu system

I have a UIViewcontroller that has a UITableView and and a couple of buttons, (add and done)
When the user clicks add I need to get some details (which represent a notification they are setting in the app).
Details like notification name, a number, target score etc...
What is the best way to get this info, is it a good idea to use a UIView and animate it onto the screen with some textfields or something like that?
Any good cocoa controls you can recommend?
Problem is my app already transitions from the rootview controller to the notification input controller modally, I was trying to get a simple UI to just enter data, I could use UIAlertViews but they are so ugly....
based on your comment above:
CustomUIView *inputView = [UIView alloc]initWithFrame:CGRectMake(offscreenRect)];
inputView.alpha = 0;
self.notificationInputController.userInactionEnabled = NO;
[UIView animateWithDuration:.5
animations:^{
inputView.alpha = 1;
inputView.rect = CGRectMake(onScreenRect);
}
completion:^(BOOL finished) {
[self.notificationInputController addSubView:inputView];
self.notificationInputController.userInactionEnabled = YES;
}];

Display and hide Textfield programmatically for iPhone/Cocoa Touch

I'm trying to create a custom editor for my UIViewController. It was suggested that I hide the textfields until the user presses the Edit key. How do you do this programmatically?
In other words when the user hits 'Edit' I would like the label to disappear and the Textfield to appear.
Thanks,
You can make use of the hidden property for quickly turning something visible or invisible.
self.widget1.hidden = YES;
self.widget2.hidden = NO;
Another option is to set alpha to 0 to hide and 1 to show. This is beneficial if you want to have an animation fade the widgets in and out for a smooth transition.
[UIView beginAnimations:nil context:NULL];
self.widget1.alpha = 0;
self.widget2.alpha = 1;
[UIView commitAnimations];
You just need to use the hidden property.
label.hidden = YES;
textField.hidden = NO;

Alternative to CGAffineTransformConcat

In the app I'm working on the user taps on a tableview to zoom it up to full view from a "thumbnail" or a miniature view. Everything is working great except for a somewhat annoying animation glitch or whatever. The thing is I'm using the code below:
if ([subview respondsToSelector:#selector (name)] && [subview.name isEqualToString:self.labelListName.text])
{
[self.tabBarController.view addSubview:subview];
CGRect frame = CGRectMake(35, 78, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
subview.frame = frame;
CGAffineTransform scale = CGAffineTransformMakeScale(1.39, 1.39);
CGAffineTransform move = CGAffineTransformMakeTranslation(0,44);
CGAffineTransform transform = CGAffineTransformConcat(scale, move);
[UIView animateWithDuration:0.15
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
subview.transform = transform;
}
completion:^(BOOL finished){ [self goToList],subview.hidden = YES; }];
}
- (void)goToList
{
self.gotoWishList = [[WishList alloc] initWithNibName:#"WishList" bundle:nil];
self.gotoWishList.hidesBottomBarWhenPushed=YES;
self.gotoWishList.name = self.labelListName.text;
[self.navigationController pushViewController:self.gotoWishList animated:NO];
self.gotoWishList.scrollLists = self;
[WishList release];
}
And when doing the animation the transfer between the zoom view and the actual view the user is going to interact with is not completely perfect. The text inside the cell jumps a little when switching between the views. The problem lies in the translation matrix. If I skip that I can get the animation to work perfectly but then of course I need to move the miniature view down in the GUI which is not an option. If I instead do the animations in another order (move, scale) then it works better. I still get a jump at the end but it looks better, as everything jumps...and not just the text.
So...basically my question is how can I make this animation fluent. I read that the CGAffineTransformConcat still does each animation separately, and I really need both animations (scaling and moving the list) to be ONE fluent animation.
Thanks for any tips!
I think you will have to nest views/graphic-context to get what you want. The animation system doesn't support simultaneous animations because the mathematics of doing so requires an exponential amount of computational power. You might be able to trick it by sliding one view while enlarging the other.
I'm not sure about that as I have never had need to try it.
You might also be getting a jerk or skip from the tableview itself. The bounce at the top and end of scrolls can produce effects if you radically resize the table on the fly. I would turn all that off and see if you still have the problem. You might also want to test on the view independent of the tableview to make sure the problem is with the animations and not the tableview moving itself.